This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[m32c] negative pointer scales
- From: DJ Delorie <dj at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 15 Dec 2005 20:31:48 -0500
- Subject: [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")))