From c47b86425e4c37be4d2d73d8781bd8cb2424af0f Mon Sep 17 00:00:00 2001 From: dj Date: Fri, 16 Dec 2005 01:31:39 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@108620 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/config/m32c/m32c.c | 24 ++++++++++++++++++++++++ gcc/config/m32c/muldiv.md | 19 ++++++++++++++++--- gcc/config/m32c/predicates.md | 5 +++++ 4 files changed, 51 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0690daa..584f6e5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-12-15 DJ Delorie + + * 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. + 2005-12-16 Jan Hubicka PR rtl-optimization/25224 diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 97b0953..8580922 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -2798,6 +2798,30 @@ m32c_prepare_shift (rtx * operands, int scale, int bits) 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 diff --git a/gcc/config/m32c/muldiv.md b/gcc/config/m32c/muldiv.md index e80d4dc..bf6f357 100644 --- a/gcc/config/m32c/muldiv.md +++ b/gcc/config/m32c/muldiv.md @@ -127,16 +127,29 @@ ; 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" diff --git a/gcc/config/m32c/predicates.md b/gcc/config/m32c/predicates.md index 362f20d..0c80e1a 100644 --- a/gcc/config/m32c/predicates.md +++ b/gcc/config/m32c/predicates.md @@ -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\")"))) -- 2.7.4