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]

[m32c] negative pointer scales


Applied to trunk.

2005-12-15  DJ Delorie  <dj@redhat.com>

	* config/m32c/predicates.md (m32c_psi_scale): New.
	* config/m32c/m32c.c (m32c_expand_neg_mulpsi3): New.
	* config/m32c/muldiv.md (mulpsi3): Support negative constants.

Index: config/m32c/predicates.md
===================================================================
--- config/m32c/predicates.md	(revision 108619)
+++ config/m32c/predicates.md	(working copy)
@@ -195,3 +195,8 @@
   (ior (match_operand 0 "m32c_r0_operand")
        (ior (match_operand 0 "m32c_mem0_operand")
 	    (match_code "parallel"))))
+
+; TRUE for constants we can multiply pointers by
+(define_predicate "m32c_psi_scale"
+  (and (match_operand 0 "const_int_operand")
+       (match_test "m32c_const_ok_for_constraint_p(INTVAL(op), 'I', \"Ilb\")")))
Index: config/m32c/m32c.c
===================================================================
--- config/m32c/m32c.c	(revision 108619)
+++ config/m32c/m32c.c	(working copy)
@@ -2798,6 +2798,30 @@
   return 0;
 }
 
+/* The m32c has a limited range of operations that work on PSImode
+   values; we have to expand to SI, do the math, and truncate back to
+   PSI.  Yes, this is expensive, but hopefully gcc will learn to avoid
+   those cases.  */
+void
+m32c_expand_neg_mulpsi3 (rtx * operands)
+{
+  /* operands: a = b * i */
+  rtx temp1; /* b as SI */
+  rtx temp2; /* -b as SI */
+  rtx temp3; /* -b as PSI */
+  rtx scale;
+
+  temp1 = gen_reg_rtx (SImode);
+  temp2 = gen_reg_rtx (SImode);
+  temp3 = gen_reg_rtx (PSImode);
+  scale = GEN_INT (- INTVAL (operands[2]));
+
+  emit_insn (gen_zero_extendpsisi2 (temp1, operands[1]));
+  emit_insn (gen_negsi2 (temp2, temp1));
+  emit_insn (gen_truncsipsi2 (temp3, temp2));
+  emit_insn (gen_mulpsi3 (operands[0], temp3, scale));
+}
+
 /* Pattern Output Functions */
 
 /* Returns TRUE if the current function is a leaf, and thus we can
Index: config/m32c/muldiv.md
===================================================================
--- config/m32c/muldiv.md	(revision 108619)
+++ config/m32c/muldiv.md	(working copy)
@@ -127,18 +127,31 @@
 
 
 ; GCC expects to be able to multiply pointer-sized integers too, but
-; fortunately it only multiplies by powers of two.
-(define_insn "mulpsi3"
+; fortunately it only multiplies by powers of two, although sometimes
+; they're negative.
+(define_insn "mulpsi3_op"
   [(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
 	(mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
-		  (match_operand 2 "const_int_operand" "Ilb")))]
+		  (match_operand 2 "m32c_psi_scale" "Ilb")))]
   "TARGET_A24"
   "shl.l\t%b2,%0"
   [(set_attr "flags" "szc")]
   )
 
+(define_expand "mulpsi3"
+  [(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
+	(mult:PSI (match_operand:PSI 1 "mra_operand" "%0")
+		  (match_operand 2 "m32c_psi_scale" "Ilb")))]
+  "TARGET_A24"
+  "if (INTVAL(operands[2]) < 0)
+     {
+       m32c_expand_neg_mulpsi3 (operands);
+       DONE;
+     }"
+  )
 
 
+
 (define_expand "divmodqi4"
   [(set (match_dup 4)
 	(sign_extend:HI (match_operand:QI 1 "register_operand" "0,0")))


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