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]

[RFA] m68k output_move_double : use POST_INC instead of INDEX


Hi all,

the following replaces a reg+index addressing into a post_inc one in
output_move_double, when possible.  This is especially useful with the
pic modes, e.g. -msep-data, where the adresses of the variables are never
constant, but always in an address-register.  `output_move-double''s signature
needed to be changed, to get the `insn'.

OK to apply ?

example:

	without patch			with the patch

	link.w %fp,#0			link.w %fp,#0
	move.l %a5,-(%sp)		move.l %a5,-(%sp)
	move.l b@GOT(%a5),%a1		move.l b@GOT(%a5),%a1
	move.l a@GOT(%a5),%a0		move.l a@GOT(%a5),%a0
	move.l (%a1),%d0	      | move.l (%a1)+,%d0
	move.l 4(%a1),%d1	      | move.l (%a1)+,%d1
	move.l %d0,(%a0)	      | move.l %d0,(%a0)+
	move.l %d1,4(%a0)	      | move.l %d1,(%a0)+
	move.l (%sp)+,%a5		move.l (%sp)+,%a5
	unlk %fp			unlk %fp
	rts				rts

Index: gcc/config/m68k/m68k.c
===================================================================
--- gcc/config/m68k/m68k.c	(revision 123959)
+++ gcc/config/m68k/m68k.c	(working copy)
@@ -2440,7 +2440,7 @@
    with operands OPERANDS.  */
 
 const char *
-output_move_double (rtx *operands)
+output_move_double (rtx insn, rtx *operands)
 {
   enum
     {
@@ -2526,6 +2526,35 @@
       optype1 = OFFSOP;
     }
 
+  /* If an operand is a simple register indirect, and that the register
+     is dead afterwards, POST_INC is cheaper than register + offset.  */
+
+  if (optype0 == OFFSOP && optype1 != PUSHOP)
+    {
+      rtx op0 = XEXP (operands[0], 0);
+
+      if (REG_P (op0) && find_reg_note (insn, REG_DEAD, op0)
+	  && ! reg_overlap_mentioned_p (op0, operands[1]))
+	{
+	operands[0] = gen_rtx_MEM (GET_MODE (operands[0]),
+						gen_rtx_POST_INC (SImode, op0));
+	optype0 = POPOP;
+	}
+    }
+
+  if (optype1 == OFFSOP && optype0 != PUSHOP)
+    {
+      rtx op0 = XEXP (operands[1], 0);
+
+      if (REG_P (op0) && find_reg_note (insn, REG_DEAD, op0)
+	  && ! reg_overlap_mentioned_p (op0, operands[0]))
+	{
+	operands[1] = gen_rtx_MEM (GET_MODE (operands[1]),
+						gen_rtx_POST_INC (SImode, op0));
+	optype1 = POPOP;
+	}
+    }
+
   /* If an operand is an unoffsettable memory ref, find a register
      we can increment temporarily to make it refer to the second word.  */
 
Index: gcc/config/m68k/m68k.md
===================================================================
--- gcc/config/m68k/m68k.md	(revision 123959)
+++ gcc/config/m68k/m68k.md	(working copy)
@@ -157,7 +157,7 @@
 {
   if (FP_REG_P (operands[1]))
     return "fmove%.d %f1,%0";
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn "pushdi"
@@ -165,7 +165,7 @@
 	(match_operand:DI 1 "general_operand" "ro<>Fi"))]
   ""
 {
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 ;; We don't want to allow a constant operand for test insns because
@@ -193,7 +193,7 @@
 
       xoperands[0] = operands[2];
       xoperands[1] = operands[0];
-      output_move_double (xoperands);
+      output_move_double (insn, xoperands);
       cc_status.flags |= CC_REVERSED;
       return "neg%.l %R2\;negx%.l %2";
     }
@@ -1000,7 +1000,7 @@
       else
         return "fmove%.d %f1,%0";
     }
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn "movdf_cf_soft"
@@ -1008,7 +1008,7 @@
 	(match_operand:DF 1 "general_operand" "g,r"))]
   "TARGET_COLDFIRE && !TARGET_COLDFIRE_FPU"
 {
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn "movdf_cf_hard"
@@ -1031,7 +1031,7 @@
     case 3:
       return "move%.l %R1,%-;move%.l %1,%-;fdmove%.d %+,%0";
     case 4: case 5: case 6:
-      return output_move_double (operands);
+      return output_move_double (insn, operands);
     case 7:
       REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
       REAL_VALUE_TO_TARGET_DOUBLE (r, l);
@@ -1119,7 +1119,7 @@
       /* Must be memory destination.  */
       return "fmove%.x %f1,%0";
     }
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn ""
@@ -1158,14 +1158,14 @@
       else
         return "fmove%.x %f1,%0";
     }
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn ""
   [(set (match_operand:XF 0 "nonimmediate_operand" "=r,g")
 	(match_operand:XF 1 "nonimmediate_operand" "g,r"))]
   "! TARGET_68881 && TARGET_COLDFIRE"
-  "* return output_move_double (operands);")
+  "* return output_move_double (insn, operands);")
 
 (define_expand "movdi"
   ;; Let's see if it really still needs to handle fp regs, and, if so, why.
@@ -1212,14 +1212,14 @@
       else
         return "fmove%.d %f1,%0";
     }
-  return output_move_double (operands);
+  return output_move_double (insn, operands);
 })
 
 (define_insn ""
   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,g")
 	(match_operand:DI 1 "general_operand" "g,r"))]
   "TARGET_COLDFIRE"
-  "* return output_move_double (operands);")
+  "* return output_move_double (insn, operands);")
 
 ;; Thus goes after the move instructions
 ;; because the move instructions are better (require no spilling)
Index: gcc/config/m68k/m68k-protos.h
===================================================================
--- gcc/config/m68k/m68k-protos.h	(revision 123959)
+++ gcc/config/m68k/m68k-protos.h	(working copy)
@@ -32,7 +32,7 @@
 extern const char *output_move_qimode (rtx *);
 extern const char *output_move_stricthi (rtx *);
 extern const char *output_move_strictqi (rtx *);
-extern const char *output_move_double (rtx *);
+extern const char *output_move_double (rtx, rtx *);
 extern const char *output_move_const_single (rtx *);
 extern const char *output_move_const_double (rtx *);
 extern const char *output_btst (rtx *, rtx, rtx, rtx, int);
-- 
Philippe De Muyter  phdm at macqel dot be  Tel +32 27029044
Macq Electronique SA  rue de l'Aeronef 2  B-1140 Bruxelles  Fax +32 27029077


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