[PATCH] movdf/movtf SPARC rewrite

Jakub Jelinek jakub@redhat.com
Thu Mar 30 06:38:00 GMT 2000


Hi!

This patch rewrites the movdf/movtf patterns on SPARC so that there is only
one pattern for each relevant combination of switches (-m32 x -m32 -mcpu=v9
x -m32 -mvis x -m64 -mno-vis x -m64 -mvis, -mfpu x -mno-fpu) which is kept
until reload is completed, then splitted up if needed. This should remove
several ICEs. gcc with this built libm successfully, but haven't finished
the glibc building because of some completely FPU unrelated ICE IMHO related
to Kenner's current changes. I'll investigate now after I update my tree
with the changes from the last two days to see if it is not fixed yet.
David, if you have time, could you please look over the constraints if I
haven't missed anything?

2000-03-30  Jakub Jelinek  <jakub@redhat.com>

	* config/sparc/sparc.md (movdi_insn_sp64_novis): New pattern.
	(movdi_insn_sp64_vis): Renamed from movdi_insn_sp64.
	(movsf): Move fp_zero_operand check below the const0_rtx check.
	(movdf): Likewise. Also allow fp_zero_operand for stores into
	memory.
	(movtf): Likewise.
	(clear_df, clear_dfp, movdf_const_intreg_sp32,
	movdf_const_intreg_sp64): Remove.
	(movdf_insn_sp32, movdf_no_e_insn_sp32): Redo constraints and
	conditions.
	(movdf_no_e_insn_v9_sp32): New pattern.
	(movdf_insn_v9only): Remove.
	(movdf_insn_v9only_novis, movdf_insn_v9only_vis): New patterns.
	(movdf_insn_sp64): Remove.
	(movdf_insn_sp64_novis, movdf_insn_sp64_vis): New patterns.
	(movdf_no_e_insn_sp64): Allow storing 0.0 into memory.
	(following splits): Rewrite conditions. Add two new splits
	for storing 0.0 into memory and registers.
	(clear_tf, clear_tf+1, clear_tfp, clear_tfp+1): Remove.
	(movtf_insn_sp32): Redo constraints and conditions.
	(movtf_insn_vis_sp32): New pattern.
	(movtf_no_e_insn_sp32): Redo constraints and conditions.
	(movtf_insn_hq_sp64): Likewise.
	(movtf_insn_hq_vis_sp64): New pattern.
	(movtf_insn_sp64): Redo constraints and conditions.
	(movtf_insn_vis_sp64): New pattern.
	(movtf_no_e_insn_sp64): Redo constraints and conditions.
	(movtf_no_e_insn_sp64+1): New split for storing 0.0L into registers
	or memory.
	* config/sparc/sparc.c (sparc_override_options): Assume v9 if either
	-mvis or -m64 to take down the number of various reload patterns.

--- gcc/config/sparc/sparc.md.jj	Tue Mar 28 13:22:52 2000
+++ gcc/config/sparc/sparc.md	Thu Mar 30 11:37:31 2000
@@ -2568,10 +2568,28 @@
   [(set_attr "type" "move")
    (set_attr "length" "1")])
 
-(define_insn "*movdi_insn_sp64"
+(define_insn "*movdi_insn_sp64_novis"
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m")
+        (match_operand:DI 1 "input_operand"   "rI,K,J,m,rJ,e,m,e"))]
+  "TARGET_ARCH64 && ! TARGET_VIS &&
+   (register_operand (operands[0], DImode)
+    || reg_or_0_operand (operands[1], DImode))"
+  "@
+   mov\\t%1, %0
+   sethi\\t%%hi(%a1), %0
+   clr\\t%0
+   ldx\\t%1, %0
+   stx\\t%r1, %0
+   fmovd\\t%1, %0
+   ldd\\t%1, %0
+   std\\t%1, %0"
+  [(set_attr "type" "move,move,move,load,store,fpmove,fpload,fpstore")
+   (set_attr "length" "1")])
+
+(define_insn "*movdi_insn_sp64_vis"
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,r,m,?e,?e,?m,b")
         (match_operand:DI 1 "input_operand"   "rI,K,J,m,rJ,e,m,e,J"))]
-  "TARGET_ARCH64 &&
+  "TARGET_ARCH64 && TARGET_VIS &&
    (register_operand (operands[0], DImode)
     || reg_or_0_operand (operands[1], DImode))"
   "@
@@ -3127,14 +3145,15 @@
   if (GET_CODE (operands[0]) == REG
       && CONSTANT_P (operands[1]))
     {
-      if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
-	goto movsf_is_ok;
-
       /* emit_group_store will send such bogosity to us when it is
          not storing directly into memory.  So fix this up to avoid
          crashes in output_constant_pool.  */
       if (operands [1] == const0_rtx)
         operands[1] = CONST0_RTX (SFmode);
+
+      if (TARGET_VIS && fp_zero_operand (operands[1], SFmode))
+	goto movsf_is_ok;
+
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
                                                    operands[1]));
     }
@@ -3174,101 +3193,6 @@
   ;
 }")
 
-(define_insn "*clear_df"
-  [(set (match_operand:DF 0 "register_operand" "=e")
-        (match_operand:DF 1 "fp_zero_operand" ""))]
-  "TARGET_VIS"
-  "fzero\\t%0"
-  [(set_attr "type" "fpmove")
-   (set_attr "length" "1")])
-
-(define_insn "*clear_dfp"
-  [(set (match_operand:DF 0 "memory_operand" "=m")
-        (match_operand:DF 1 "fp_zero_operand" ""))]
-  "TARGET_V9"
-  "stx\\t%%g0, %0"
-  [(set_attr "type" "store")
-   (set_attr "length" "1")])
-
-(define_insn "*movdf_const_intreg_sp32"
-  [(set (match_operand:DF 0 "register_operand" "=e,e,?r")
-        (match_operand:DF 1 "const_double_operand" "T#F,o#F,F"))]
-  "TARGET_FPU && ! TARGET_ARCH64"
-  "@
-   ldd\\t%1, %0
-   #
-   #"
-  [(set_attr "type" "move")
-   (set_attr "length" "1,2,2")])
-
-;; Now that we redo life analysis with a clean slate after
-;; instruction splitting for sched2 this can work.
-(define_insn "*movdf_const_intreg_sp64"
-  [(set (match_operand:DF 0 "register_operand" "=e,?r")
-        (match_operand:DF 1 "const_double_operand" "m#F,F"))]
-  "TARGET_FPU && TARGET_ARCH64"
-  "@
-   ldd\\t%1, %0
-   #"
-  [(set_attr "type" "move")
-   (set_attr "length" "1,2")])
-
-(define_split
-  [(set (match_operand:DF 0 "register_operand" "")
-        (match_operand:DF 1 "const_double_operand" ""))]
-  "TARGET_FPU
-   && (GET_CODE (operands[0]) == REG
-       && REGNO (operands[0]) < 32)
-   && reload_completed"
-  [(clobber (const_int 0))]
-  "
-{
-  REAL_VALUE_TYPE r;
-  long l[2];
-
-  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
-  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
-  if (GET_CODE (operands[0]) == SUBREG)
-    operands[0] = alter_subreg (operands[0]);
-  operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
-
-  if (TARGET_ARCH64)
-    {
-#if HOST_BITS_PER_WIDE_INT == 64
-      HOST_WIDE_INT val;
-
-      val = ((HOST_WIDE_INT)(unsigned long)l[1] |
-             ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
-      emit_insn (gen_movdi (operands[0], GEN_INT (val)));
-#else
-      emit_insn (gen_movdi (operands[0],
-                            gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
-                                                  l[1], l[0])));
-#endif
-    }
-  else
-    {
-      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
-			    GEN_INT (l[0])));
-
-      /* Slick... but this trick loses if this subreg constant part
-         can be done in one insn.  */
-      if (l[1] == l[0]
-          && !(SPARC_SETHI_P (l[0])
-	       || SPARC_SIMM13_P (l[0])))
-        {
-          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			        gen_highpart (SImode, operands[0])));
-        }
-      else
-        {
-          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
-			        GEN_INT (l[1])));
-        }
-    }
-  DONE;
-}")
-
 (define_expand "movdf"
   [(set (match_operand:DF 0 "general_operand" "")
 	(match_operand:DF 1 "general_operand" ""))]
@@ -3279,14 +3203,15 @@
   if (GET_CODE (operands[0]) == REG
       && CONSTANT_P (operands[1]))
     {
-      if (TARGET_VIS && fp_zero_operand (operands[1], DFmode))
-	goto movdf_is_ok;
-
       /* emit_group_store will send such bogosity to us when it is
          not storing directly into memory.  So fix this up to avoid
          crashes in output_constant_pool.  */
       if (operands [1] == const0_rtx)
         operands[1] = CONST0_RTX (DFmode);
+
+      if (TARGET_VIS && fp_zero_operand (operands[1], DFmode))
+	goto movdf_is_ok;
+
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
                                                    operands[1]));
     }
@@ -3294,7 +3219,8 @@
   /* Handle MEM cases first.  */
   if (GET_CODE (operands[0]) == MEM)
     {
-      if (register_operand (operands[1], DFmode))
+      if (register_operand (operands[1], DFmode)
+	  || fp_zero_operand (operands[1], DFmode))
 	goto movdf_is_ok;
 
       if (! reload_in_progress)
@@ -3327,12 +3253,13 @@
 
 ;; Be careful, fmovd does not exist when !v9.
 (define_insn "*movdf_insn_sp32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,e,r,r,o,e,o")
-	(match_operand:DF 1 "input_operand"    "T,e,T,U,e,r,o,r,o,e"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,T,U,T,o,e,*r,o,e,o")
+	(match_operand:DF 1 "input_operand"    "T#F,e,T,U,G,e,*rFo,*r,o#F,e"))]
   "TARGET_FPU
    && ! TARGET_V9
    && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
   "@
   ldd\\t%1, %0
   std\\t%1, %0
@@ -3348,12 +3275,14 @@
   (set_attr "length" "1,1,1,1,2,2,2,2,2,2")])
 
 (define_insn "*movdf_no_e_insn_sp32"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,r,r,o")
-	(match_operand:DF 1 "input_operand"    "T,U,r,o,r"))]
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,o,r,o")
+	(match_operand:DF 1 "input_operand"    "T,U,G,ro,r"))]
   "! TARGET_FPU
+   && ! TARGET_V9
    && ! TARGET_ARCH64
    && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
   "@
   ldd\\t%1, %0
   std\\t%1, %0
@@ -3363,62 +3292,191 @@
   [(set_attr "type" "load,store,*,*,*")
    (set_attr "length" "1,1,2,2,2")])
 
+(define_insn "*movdf_no_e_insn_v9_sp32"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
+	(match_operand:DF 1 "input_operand"    "T,U,G,ro,rG"))]
+  "! TARGET_FPU
+   && TARGET_V9
+   && ! TARGET_ARCH64
+   && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
+  "@
+  ldd\\t%1, %0
+  std\\t%1, %0
+  stx\\t%r1, %0
+  #
+  #"
+  [(set_attr "type" "load,store,store,*,*")
+   (set_attr "length" "1,1,1,2,2")])
+
 ;; We have available v9 double floats but not 64-bit
-;; integer registers.
-(define_insn "*movdf_insn_v9only"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,U,T,r,r,o")
-        (match_operand:DF 1 "input_operand"    "e,m,e,T,U,r,o,r"))]
+;; integer registers and no VIS.
+(define_insn "*movdf_insn_v9only_novis"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,T,T,U,T,e,*r,o")
+        (match_operand:DF 1 "input_operand"    "e,T#F,G,e,T,U,o#F,*roF,*rGe"))]
   "TARGET_FPU
    && TARGET_V9
+   && ! TARGET_VIS
+   && ! TARGET_ARCH64
+   && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
+  "@
+  fmovd\\t%1, %0
+  ldd\\t%1, %0
+  stx\\t%r1, %0
+  std\\t%1, %0
+  ldd\\t%1, %0
+  std\\t%1, %0
+  #
+  #
+  #"
+  [(set_attr "type" "fpmove,load,store,store,load,store,*,*,*")
+   (set_attr "length" "1,1,1,1,1,1,2,2,2")])
+
+;; We have available v9 double floats but not 64-bit
+;; integer registers but we have VIS.
+(define_insn "*movdf_insn_v9only_vis"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,T,T,U,T,e,*r,o")
+        (match_operand:DF 1 "input_operand" "G,e,T#F,G,e,T,U,o#F,*roGF,*rGe"))]
+  "TARGET_FPU
+   && TARGET_VIS
    && ! TARGET_ARCH64
    && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
   "@
+  fzero\\t%1, %0
   fmovd\\t%1, %0
   ldd\\t%1, %0
+  stx\\t%r1, %0
   std\\t%1, %0
   ldd\\t%1, %0
   std\\t%1, %0
   #
   #
   #"
-  [(set_attr "type" "fpmove,load,store,load,store,*,*,*")
-   (set_attr "length" "1,1,1,1,1,2,2,2")])
+  [(set_attr "type" "fpmove,fpmove,load,store,store,load,store,*,*,*")
+   (set_attr "length" "1,1,1,1,1,1,1,2,2,2")])
 
 ;; We have available both v9 double floats and 64-bit
-;; integer registers.
-(define_insn "*movdf_insn_sp64"
-  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,r,r,m")
-        (match_operand:DF 1 "input_operand"    "e,m,e,r,m,r"))]
+;; integer registers. No VIS though.
+(define_insn "*movdf_insn_sp64_novis"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,m,*r,*r,m,*r")
+        (match_operand:DF 1 "input_operand"    "e,m#F,e,*rG,m,*rG,F"))]
   "TARGET_FPU
-   && TARGET_V9
+   && ! TARGET_VIS
    && TARGET_ARCH64
    && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
   "@
   fmovd\\t%1, %0
   ldd\\t%1, %0
   std\\t%1, %0
-  mov\\t%1, %0
+  mov\\t%r1, %0
   ldx\\t%1, %0
-  stx\\t%1, %0"
-  [(set_attr "type" "fpmove,load,store,move,load,store")
-   (set_attr "length" "1")])
+  stx\\t%r1, %0
+  #"
+  [(set_attr "type" "fpmove,load,store,move,load,store,*")
+   (set_attr "length" "1,1,1,1,1,1,2")])
+
+;; We have available both v9 double floats and 64-bit
+;; integer registers. And we have VIS.
+(define_insn "*movdf_insn_sp64_vis"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "=e,e,e,m,*r,*r,m,*r")
+        (match_operand:DF 1 "input_operand"    "G,e,m#F,e,*rG,m,*rG,F"))]
+  "TARGET_FPU
+   && TARGET_VIS
+   && TARGET_ARCH64
+   && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
+  "@
+  fzero\\t%0
+  fmovd\\t%1, %0
+  ldd\\t%1, %0
+  std\\t%1, %0
+  mov\\t%r1, %0
+  ldx\\t%1, %0
+  stx\\t%r1, %0
+  #"
+  [(set_attr "type" "fpmove,fpmove,load,store,move,load,store,*")
+   (set_attr "length" "1,1,1,1,1,1,1,2")])
 
 (define_insn "*movdf_no_e_insn_sp64"
   [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")
-        (match_operand:DF 1 "input_operand"    "r,m,r"))]
+        (match_operand:DF 1 "input_operand"    "r,m,rG"))]
   "! TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], DFmode)
-       || register_operand (operands[1], DFmode))"
+       || register_operand (operands[1], DFmode)
+       || fp_zero_operand (operands[1], DFmode))"
   "@
   mov\\t%1, %0
   ldx\\t%1, %0
-  stx\\t%1, %0"
+  stx\\t%r1, %0"
   [(set_attr "type" "move,load,store")
    (set_attr "length" "1")])
 
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+        (match_operand:DF 1 "const_double_operand" ""))]
+  "TARGET_FPU
+   && (GET_CODE (operands[0]) == REG
+       && REGNO (operands[0]) < 32)
+   && ! fp_zero_operand(operands[1], DFmode)
+   && reload_completed"
+  [(clobber (const_int 0))]
+  "
+{
+  REAL_VALUE_TYPE r;
+  long l[2];
+
+  REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
+  REAL_VALUE_TO_TARGET_DOUBLE (r, l);
+  if (GET_CODE (operands[0]) == SUBREG)
+    operands[0] = alter_subreg (operands[0]);
+  operands[0] = gen_rtx_raw_REG (DImode, REGNO (operands[0]));
+
+  if (TARGET_ARCH64)
+    {
+#if HOST_BITS_PER_WIDE_INT == 64
+      HOST_WIDE_INT val;
+
+      val = ((HOST_WIDE_INT)(unsigned long)l[1] |
+             ((HOST_WIDE_INT)(unsigned long)l[0] << 32));
+      emit_insn (gen_movdi (operands[0], GEN_INT (val)));
+#else
+      emit_insn (gen_movdi (operands[0],
+                            gen_rtx_CONST_DOUBLE (VOIDmode, const0_rtx,
+                                                  l[1], l[0])));
+#endif
+    }
+  else
+    {
+      emit_insn (gen_movsi (gen_highpart (SImode, operands[0]),
+			    GEN_INT (l[0])));
+
+      /* Slick... but this trick loses if this subreg constant part
+         can be done in one insn.  */
+      if (l[1] == l[0]
+          && !(SPARC_SETHI_P (l[0])
+	       || SPARC_SIMM13_P (l[0])))
+        {
+          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
+			        gen_highpart (SImode, operands[0])));
+        }
+      else
+        {
+          emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
+			        GEN_INT (l[1])));
+        }
+    }
+  DONE;
+}")
+
 ;; Ok, now the splits to handle all the multi insn and
 ;; mis-aligned memory address cases.
 ;; In these splits please take note that we must be
@@ -3471,17 +3529,11 @@
 (define_split
   [(set (match_operand:DF 0 "register_operand" "")
 	(match_operand:DF 1 "memory_operand" ""))]
-  "((! TARGET_V9
-     || (! TARGET_ARCH64
-         && ((GET_CODE (operands[0]) == REG
-              && REGNO (operands[0]) < 32)
-             || (GET_CODE (operands[0]) == SUBREG
-                 && GET_CODE (SUBREG_REG (operands[0])) == REG
-                 && REGNO (SUBREG_REG (operands[0])) < 32))))
-    && (reload_completed
-        && (((REGNO (operands[0])) % 2) != 0
-             || ! mem_min_alignment (operands[1], 8))
-        && offsettable_memref_p (operands[1])))"
+  "reload_completed
+   && ! TARGET_ARCH64
+   && (((REGNO (operands[0]) % 2) != 0)
+       || ! mem_min_alignment (operands[1], 8))
+   && offsettable_memref_p (operands[1])"
   [(clobber (const_int 0))]
   "
 {
@@ -3512,17 +3564,11 @@
 (define_split
   [(set (match_operand:DF 0 "memory_operand" "")
 	(match_operand:DF 1 "register_operand" ""))]
-  "((! TARGET_V9
-     || (! TARGET_ARCH64
-         && ((GET_CODE (operands[1]) == REG
-              && REGNO (operands[1]) < 32)
-             || (GET_CODE (operands[1]) == SUBREG
-                 && GET_CODE (SUBREG_REG (operands[1])) == REG
-                 && REGNO (SUBREG_REG (operands[1])) < 32))))
-    && (reload_completed
-        && (((REGNO (operands[1])) % 2) != 0
-             || ! mem_min_alignment (operands[0], 8))
-        && offsettable_memref_p (operands[0])))"
+  "reload_completed
+   && ! TARGET_ARCH64
+   && (((REGNO (operands[1]) % 2) != 0)
+       || ! mem_min_alignment (operands[0], 8))
+   && offsettable_memref_p (operands[0])"
   [(clobber (const_int 0))]
   "
 {
@@ -3539,45 +3585,51 @@
   DONE;
 }")
 
-(define_insn "*clear_tf"
-  [(set (match_operand:TF 0 "register_operand" "=e")
-        (match_operand:TF 1 "fp_zero_operand" ""))]
-  "TARGET_VIS"
-  "#"
-  [(set_attr "type" "fpmove")
-   (set_attr "length" "2")])
-
 (define_split
-  [(set (match_operand:TF 0 "register_operand" "")
-        (match_operand:TF 1 "fp_zero_operand" ""))]
-  "TARGET_VIS && reload_completed"
-  [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
-   (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
+  [(set (match_operand:DF 0 "memory_operand" "")
+        (match_operand:DF 1 "fp_zero_operand" ""))]
+  "reload_completed
+   && (! TARGET_V9
+       || (! TARGET_ARCH64
+	   && ! mem_min_alignment (operands[0], 8)))
+   && offsettable_memref_p (operands[0])"
+  [(clobber (const_int 0))]
   "
 {
-  operands[1] = CONST0_RTX (DFmode);
-}
-")
+  rtx dest1, dest2;
 
-(define_insn "*clear_tfp"
-  [(set (match_operand:TF 0 "memory_operand" "=m")
-        (match_operand:TF 1 "fp_zero_operand" ""))]
-  "TARGET_V9"
-  "#"
-  [(set_attr "type" "fpmove")
-   (set_attr "length" "2")])
+  dest1 = change_address (operands[0], SFmode, NULL_RTX);
+  dest2 = change_address (operands[0], SFmode,
+			  plus_constant_for_output (XEXP (dest1, 0), 4));
+  emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
+  emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+  DONE;
+}")
 
 (define_split
-  [(set (match_operand:TF 0 "memory_operand" "=m")
-        (match_operand:TF 1 "fp_zero_operand" ""))]
-  "TARGET_V9 && reload_completed"
-  [(set (subreg:DF (match_dup 0) 0) (match_dup 1))
-   (set (subreg:DF (match_dup 0) 8) (match_dup 1))]
+  [(set (match_operand:DF 0 "register_operand" "")
+        (match_operand:DF 1 "fp_zero_operand" ""))]
+  "reload_completed
+   && ! TARGET_ARCH64
+   && ((GET_CODE (operands[0]) == REG
+	&& REGNO (operands[0]) < 32)
+       || (GET_CODE (operands[0]) == SUBREG
+	   && GET_CODE (SUBREG_REG (operands[0])) == REG
+	   && REGNO (SUBREG_REG (operands[0])) < 32))"
+  [(clobber (const_int 0))]
   "
 {
-  operands[1] = CONST0_RTX (DFmode);
-}
-")
+  rtx set_dest = operands[0];
+  rtx dest1, dest2;
+
+  if (GET_CODE (set_dest) == SUBREG)
+    set_dest = alter_subreg (set_dest);
+  dest1 = gen_highpart (SFmode, set_dest);
+  dest2 = gen_lowpart (SFmode, set_dest);
+  emit_insn (gen_movsf (dest1, CONST0_RTX (SFmode)));
+  emit_insn (gen_movsf (dest2, CONST0_RTX (SFmode)));
+  DONE;
+}")
 
 (define_expand "movtf"
   [(set (match_operand:TF 0 "general_operand" "")
@@ -3589,14 +3641,15 @@
   if (GET_CODE (operands[0]) == REG
       && CONSTANT_P (operands[1]))
     {
-      if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
-	goto movtf_is_ok;
-
       /* emit_group_store will send such bogosity to us when it is
          not storing directly into memory.  So fix this up to avoid
          crashes in output_constant_pool.  */
       if (operands [1] == const0_rtx)
         operands[1] = CONST0_RTX (TFmode);
+
+      if (TARGET_VIS && fp_zero_operand (operands[1], TFmode))
+	goto movtf_is_ok;
+
       operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
                                                    operands[1]));
     }
@@ -3605,8 +3658,9 @@
      full 16-byte alignment for quads. */
   if (GET_CODE (operands[0]) == MEM)
     {
-      if (register_operand (operands[1], TFmode))
-        goto movtf_is_ok;
+      if (register_operand (operands[1], TFmode)
+	  || fp_zero_operand (operands[1], TFmode))
+	goto movtf_is_ok;
 
       if (! reload_in_progress)
 	{
@@ -3639,12 +3693,26 @@
 ;; Be careful, fmovq and {st,ld}{x,q} do not exist when !arch64 so
 ;; we must split them all.  :-(
 (define_insn "*movtf_insn_sp32"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,e,r,r,o")
-	(match_operand:TF 1 "input_operand"    "o,e,o,U,e,r,o,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o")
+	(match_operand:TF 1 "input_operand"    "oe,Ge,o,U,ro,r"))]
   "TARGET_FPU
+   && ! TARGET_VIS
    && ! TARGET_ARCH64
    && (register_operand (operands[0], TFmode)
-       || register_operand (operands[1], TFmode))"
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
+  "#"
+  [(set_attr "length" "4")])
+
+(define_insn "*movtf_insn_vis_sp32"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,U,o,r,o")
+	(match_operand:TF 1 "input_operand"    "Goe,Ge,o,U,ro,r"))]
+  "TARGET_FPU
+   && TARGET_VIS
+   && ! TARGET_ARCH64
+   && (register_operand (operands[0], TFmode)
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
   "#"
   [(set_attr "length" "4")])
 
@@ -3653,26 +3721,48 @@
 ;; when -mno-fpu.
 
 (define_insn "*movtf_no_e_insn_sp32"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=U,o,r,r,o")
-	(match_operand:TF 1 "input_operand"    "o,U,r,o,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,U,o,r,o")
+	(match_operand:TF 1 "input_operand"    "G,o,U,ro,r"))]
   "! TARGET_FPU
    && ! TARGET_ARCH64
    && (register_operand (operands[0], TFmode)
-       || register_operand (operands[1], TFmode))"
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
   "#"
   [(set_attr "length" "4")])
 
 ;; Now handle the float reg cases directly when arch64,
 ;; hard_quad, and proper reg number alignment are all true.
 (define_insn "*movtf_insn_hq_sp64"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,r,r,o")
-        (match_operand:TF 1 "input_operand"    "e,m,e,r,o,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,o,r,o")
+        (match_operand:TF 1 "input_operand"    "e,m,e,G,ro,r"))]
   "TARGET_FPU
+   && ! TARGET_VIS
    && TARGET_ARCH64
-   && TARGET_V9
    && TARGET_HARD_QUAD
    && (register_operand (operands[0], TFmode)
-       || register_operand (operands[1], TFmode))"
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
+  "@
+  fmovq\\t%1, %0
+  ldq\\t%1, %0
+  stq\\t%1, %0
+  #
+  #
+  #"
+  [(set_attr "type" "fpmove,fpload,fpstore,*,*,*")
+   (set_attr "length" "1,1,1,2,2,2")])
+
+(define_insn "*movtf_insn_hq_vis_sp64"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,e,m,eo,r,o")
+        (match_operand:TF 1 "input_operand"    "e,m,e,G,ro,r"))]
+  "TARGET_FPU
+   && TARGET_VIS
+   && TARGET_ARCH64
+   && TARGET_HARD_QUAD
+   && (register_operand (operands[0], TFmode)
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
   "@
   fmovq\\t%1, %0
   ldq\\t%1, %0
@@ -3686,23 +3776,39 @@
 ;; Now we allow the integer register cases even when
 ;; only arch64 is true.
 (define_insn "*movtf_insn_sp64"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=e,o,r,o,e,r")
-        (match_operand:TF 1 "input_operand"    "o,e,o,r,e,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=o,e,r")
+        (match_operand:TF 1 "input_operand"    "Ge,oe,or"))]
+  "TARGET_FPU
+   && ! TARGET_VIS
+   && TARGET_ARCH64
+   && ! TARGET_HARD_QUAD
+   && (register_operand (operands[0], TFmode)
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
+  "#"
+  [(set_attr "length" "2")])
+
+(define_insn "*movtf_insn_vis_sp64"
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=eo,e,r")
+        (match_operand:TF 1 "input_operand"    "Ge,o,or"))]
   "TARGET_FPU
+   && TARGET_VIS
    && TARGET_ARCH64
    && ! TARGET_HARD_QUAD
    && (register_operand (operands[0], TFmode)
-       || register_operand (operands[1], TFmode))"
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
   "#"
   [(set_attr "length" "2")])
 
 (define_insn "*movtf_no_e_insn_sp64"
-  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o,r")
-        (match_operand:TF 1 "input_operand"    "o,r,r"))]
+  [(set (match_operand:TF 0 "nonimmediate_operand" "=r,o")
+        (match_operand:TF 1 "input_operand"    "or,rG"))]
   "! TARGET_FPU
    && TARGET_ARCH64
    && (register_operand (operands[0], TFmode)
-       || register_operand (operands[1], TFmode))"
+       || register_operand (operands[1], TFmode)
+       || fp_zero_operand (operands[1], TFmode))"
   "#"
   [(set_attr "length" "2")])
 
@@ -3744,6 +3850,39 @@
       emit_insn (gen_movdf (dest1, src1));
       emit_insn (gen_movdf (dest2, src2));
     }
+  DONE;
+}")
+
+(define_split
+  [(set (match_operand:TF 0 "nonimmediate_operand" "")
+        (match_operand:TF 1 "fp_zero_operand" ""))]
+  "reload_completed"
+  [(clobber (const_int 0))]
+  "
+{
+  rtx set_dest = operands[0];
+  rtx dest1, dest2;
+
+  switch (GET_CODE (set_dest))
+    {
+    case SUBREG:
+      set_dest = alter_subreg (set_dest);
+      /* FALLTHROUGH */
+    case REG:
+      dest1 = gen_df_reg (set_dest, 0);
+      dest2 = gen_df_reg (set_dest, 1);
+      break;
+    case MEM:
+      dest1 = change_address (set_dest, DFmode, NULL_RTX);
+      dest2 = change_address (set_dest, DFmode,
+			      plus_constant_for_output (XEXP (dest1, 0), 8));
+      break;
+    default:
+      abort ();      
+    }
+
+  emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
+  emit_insn (gen_movdf (dest2, CONST0_RTX (DFmode)));
   DONE;
 }")
 
--- gcc/config/sparc/sparc.c.jj	Tue Mar 28 13:22:52 2000
+++ gcc/config/sparc/sparc.c	Tue Mar 28 21:22:26 2000
@@ -341,6 +341,16 @@ sparc_override_options ()
       target_flags &= ~MASK_FPU_SET;
     }
 
+  /* Don't allow -mvis if FPU is disabled.  */
+  if (! TARGET_FPU)
+    target_flags &= ~MASK_VIS;
+
+  /* -mvis assumes UltraSPARC+, so we are sure v9 instructions
+     are available.
+     -m64 also implies v9.  */
+  if (TARGET_VIS || TARGET_ARCH64)
+    target_flags |= MASK_V9;
+
   /* Use the deprecated v8 insns for sparc64 in 32 bit mode.  */
   if (TARGET_V9 && TARGET_ARCH32)
     target_flags |= MASK_DEPRECATED_V8_INSNS;
@@ -353,10 +363,6 @@ sparc_override_options ()
   if (TARGET_ARCH32)
     target_flags &= ~MASK_STACK_BIAS;
     
-  /* Don't allow -mvis if FPU is disabled.  */
-  if (! TARGET_FPU)
-    target_flags &= ~MASK_VIS;
-
   /* Supply a default value for align_functions.  */
   if (align_functions == 0 && sparc_cpu == PROCESSOR_ULTRASPARC)
     align_functions = 32;
--- gcc/config/sparc/sparc.h.jj	Tue Mar 28 13:22:52 2000
+++ gcc/config/sparc/sparc.h	Wed Mar 29 10:18:29 2000
@@ -2307,7 +2307,7 @@ LFLGRET"ID":\n\
 #define REG_OK_FOR_BASE_P(X) \
   (((unsigned) REGNO (X)) - 32 >= (FIRST_PSEUDO_REGISTER - 32))
 
-/* 'T', 'U' are for aligned memory loads which aren't needed for v9.  */
+/* 'T', 'U' are for aligned memory loads which aren't needed for arch64.  */
 
 #define EXTRA_CONSTRAINT(OP, C)				\
    (EXTRA_CONSTRAINT_BASE(OP, C)                        \

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.99-pre2 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________


More information about the Gcc-patches mailing list