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]

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


This patch has no effect.

It ought to have an effect.  What it should do is make a short chunk
of code like this:

void foo(int *x, double d)
{ *x = d; }

generate code like:

        fctiwz f0,f1
        stfiwx f0,0,r3
        blr

instead of pointlessly generating a temporary, like:

        fctiwz f0,f1
        addi r2,r1,-24
        stfiwx f0,0,r2
        lwz r0,-24(r1)
        stw r0,0(r3)
        blr

However, it doesn't, because of this chunk of code in emit-rtl.c:

  /* If will do cse, generate all results into pseudo registers
     since 1) that allows cse to find more things
     and 2) otherwise cse could produce an insn the machine
     cannot support.  An exception is a CONSTRUCTOR into a multi-word
     MEM: that's much more likely to be most efficient into the MEM.
     Another is a CALL_EXPR which must return in memory.  */
  
  if (! cse_not_expected && mode != BLKmode && target
      && (!REG_P (target) || REGNO (target) < FIRST_PSEUDO_REGISTER)
      && ! (code == CONSTRUCTOR && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
      && ! (code == CALL_EXPR && aggregate_value_p (exp, exp)))
    target = 0;

When -O is set, cse_not_expected is always clear; at -O0, a temporary
is generated at the tree level instead.

I hope that in the future this code may be able to be removed, and
then this patch will be useful.

I'll commit after a bootstrap and testrun on powerpc-darwin8.

-- 
- Geoffrey Keating <geoffk@apple.com>

===File ~/patches/rs6000-stfiwx-memdest.patch===============
2005-05-17  Geoffrey Keating  <geoffk@apple.com>

	* rs6000/predicates.md (fix_trunc_dest_operand): New.
	* rs6000/rs6000.md (fix_truncdfsi2): Use fix_trunc_dest_operand.
	Check that a memory operand is valid before trying to use it.
	
Index: config/rs6000/predicates.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/predicates.md,v
retrieving revision 1.14
diff -u -p -u -p -r1.14 predicates.md
--- config/rs6000/predicates.md	3 May 2005 11:48:26 -0000	1.14
+++ config/rs6000/predicates.md	17 May 2005 22:26:21 -0000
@@ -364,6 +364,15 @@
 		    || GET_CODE (XEXP (XEXP (op, 0), 1)) != CONST_INT
 		    || INTVAL (XEXP (XEXP (op, 0), 1)) % 4 == 0")))
 
+;; Used for the destination of the fix_truncdfsi2 expander.
+;; If stfiwx will be used, the result goes to memory; otherwise,
+;; we're going to emit a store and a load of a subreg, so the dest is a
+;; register.
+(define_predicate "fix_trunc_dest_operand"
+  (if_then_else (match_test "! TARGET_E500_DOUBLE && TARGET_PPC_GFXOPT")
+   (match_operand 0 "memory_operand")
+   (match_operand 0 "gpc_reg_operand")))
+
 ;; Return 1 if the operand is either a non-special register or can be used
 ;; as the operand of a `mode' add insn.
 (define_predicate "add_operand"
Index: config/rs6000/rs6000.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.367
diff -u -p -u -p -r1.367 rs6000.md
--- config/rs6000/rs6000.md	9 May 2005 22:04:48 -0000	1.367
+++ config/rs6000/rs6000.md	17 May 2005 22:26:22 -0000
@@ -5329,10 +5329,8 @@
 }"
   [(set_attr "length" "20")])
 
-; 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" "")
+  [(parallel [(set (match_operand:SI 0 "fix_trunc_dest_operand" "")
 		   (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
 	      (clobber (match_dup 2))
 	      (clobber (match_dup 3))])]
@@ -5349,7 +5347,7 @@
   if (TARGET_PPC_GFXOPT)
     {
       rtx orig_dest = operands[0];
-      if (GET_CODE (orig_dest) != MEM)
+      if (! memory_operand (orig_dest, GET_MODE (orig_dest)))
 	operands[0] = assign_stack_temp (SImode, GET_MODE_SIZE (SImode), 0);
       emit_insn (gen_fix_truncdfsi2_internal_gfxopt (operands[0], operands[1],
 						     operands[2]));
============================================================


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