predicates.md (m32c_psi_scale): New.

* 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.

From-SVN: r108620
This commit is contained in:
DJ Delorie 2005-12-15 20:31:39 -05:00 committed by DJ Delorie
parent 6cb8c05915
commit 12ea2512c4
4 changed files with 51 additions and 3 deletions

View File

@ -1,3 +1,9 @@
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.
2005-12-16 Jan Hubicka <jh@suse.cz>
PR rtl-optimization/25224

View File

@ -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

View File

@ -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"

View File

@ -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\")")))