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]

Re: Still can't make stfiwx actually store directly, but...


I've tested this on all of exactly one test case.  With -O2,

	fctiwz 1,1
	stwu 1,-16(1)
	stfd 1,8(1)
	lwz 10,12(1)
	addi 1,1,16
	stw 10,0(3)
	blr

With -O2 -mcpu=G5,

	stwu 1,-16(1)
	fctiwz 0,1
	stfiwx 0,0,3
	addi 1,1,16
	blr

I assume I've missed something that's still allocating a
stack slot for this.


r~



Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.367
diff -u -p -r1.367 rs6000.md
--- config/rs6000/rs6000.md	9 May 2005 22:04:48 -0000	1.367
+++ config/rs6000/rs6000.md	18 May 2005 01:30:58 -0000
@@ -5332,72 +5332,24 @@
 ; In the TARGET_PPC_GFXOPT case, this could and probably should
 ; take a memory destination; but actually making this work is hard.
 (define_expand "fix_truncdfsi2"
-  [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
-		   (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
-	      (clobber (match_dup 2))
-	      (clobber (match_dup 3))])]
+  [(set (match_operand:SI 0 "gpc_reg_operand" "")
+	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))]
   "(TARGET_POWER2 || TARGET_POWERPC)
    && TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE)"
-  "
 {
+  rtx tmp;
+
   if (TARGET_E500_DOUBLE)
     {
-     emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1]));
-     DONE;
-    }
-  operands[2] = gen_reg_rtx (DImode);
-  if (TARGET_PPC_GFXOPT)
-    {
-      rtx orig_dest = operands[0];
-      if (GET_CODE (orig_dest) != MEM)
-	operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
-      emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
-						     operands[2]));
-      if (operands[0] != orig_dest)
-	emit_move_insn (orig_dest, operands[0]);
+      emit_insn (gen_spe_fix_truncdfsi2 (operands[0], operands[1]));
       DONE;
     }
-  operands[3] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode), 0);
-}")
-
-(define_insn_and_split "*fix_truncdfsi2_internal"
-  [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
-   (clobber (match_operand:DI 3 "memory_operand" "=o"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS"
-  "#"
-  "&& (!no_new_pseudos || offsettable_nonstrict_memref_p (operands[3]))"
-  [(pc)]
-  "
-{
-  rtx lowword;
-  gcc_assert (MEM_P (operands[3]));
-  lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
-
-  emit_insn (gen_fctiwz (operands[2], operands[1]));
-  emit_move_insn (operands[3], operands[2]);
-  emit_move_insn (operands[0], lowword);
-  DONE;
-}"
-  [(set_attr "length" "16")])
 
-(define_insn_and_split "fix_truncdfsi2_internal_gfxopt"
-  [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
-   (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))]
-  "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT && TARGET_FPRS
-   && TARGET_PPC_GFXOPT"
-  "#"
-  "&& 1"
-  [(pc)]
-  "
-{
-  emit_insn (gen_fctiwz (operands[2], operands[1]));
-  emit_insn (gen_stfiwx (operands[0], operands[2]));
+  tmp = gen_reg_rtx (DImode);
+  emit_insn (gen_fctiwz (tmp, operands[1]));
+  emit_move_insn (operands[0], gen_lowpart (SImode, tmp));
   DONE;
-}"
-  [(set_attr "length" "16")])
+})
 
 ; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
 ; rather than (set (subreg:SI (reg)) (fix:SI ...))
@@ -5414,12 +5366,34 @@
 ; An UNSPEC is used so we don't have to support SImode in FP registers.
 (define_insn "stfiwx"
   [(set (match_operand:SI 0 "memory_operand" "=Z")
-	(unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
-		   UNSPEC_STFIWX))]
+        (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "f")]
+                   UNSPEC_STFIWX))]
   "TARGET_PPC_GFXOPT"
   "stfiwx %1,%y0"
   [(set_attr "type" "fpstore")])
 
+; A pattern to allow combine to figure out when we're ultimately going to
+; be storing the value to memory.  In this case we want to use stfiwx.
+; ??? The BYTES_BIG_ENDIAN test is due to the subreg offset.  We don't
+; appear to have any way to recognize this sort of thing generically.
+(define_insn_and_split "*stfiwx_be"
+  [(set (match_operand:SI 0 "memory_operand" "=Z")
+	(subreg:SI
+	  (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))]
+		     UNSPEC_FCTIWZ)
+	  4))
+   (clobber (match_scratch:DI 2 "=f"))]
+  "TARGET_PPC_GFXOPT && BYTES_BIG_ENDIAN"
+  "#"
+  "&& (!no_new_pseudos || reload_completed)"
+  [(const_int 0)]
+{
+  rtx tmp = reload_completed ? operands[2] : gen_reg_rtx (DImode);
+  emit_insn (gen_fctiwz (tmp, operands[1]));
+  emit_insn (gen_stfiwx (operands[0], tmp));
+  DONE;
+})
+
 (define_expand "floatsisf2"
   [(set (match_operand:SF 0 "gpc_reg_operand" "")
         (float:SF (match_operand:SI 1 "gpc_reg_operand" "")))]


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