Commit 12ea2512 by DJ Delorie Committed by DJ Delorie

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
parent 6cb8c059
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> 2005-12-16 Jan Hubicka <jh@suse.cz>
PR rtl-optimization/25224 PR rtl-optimization/25224
......
...@@ -2798,6 +2798,30 @@ m32c_prepare_shift (rtx * operands, int scale, int bits) ...@@ -2798,6 +2798,30 @@ m32c_prepare_shift (rtx * operands, int scale, int bits)
return 0; 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 */ /* Pattern Output Functions */
/* Returns TRUE if the current function is a leaf, and thus we can /* Returns TRUE if the current function is a leaf, and thus we can
......
...@@ -127,16 +127,29 @@ ...@@ -127,16 +127,29 @@
; GCC expects to be able to multiply pointer-sized integers too, but ; GCC expects to be able to multiply pointer-sized integers too, but
; fortunately it only multiplies by powers of two. ; fortunately it only multiplies by powers of two, although sometimes
(define_insn "mulpsi3" ; they're negative.
(define_insn "mulpsi3_op"
[(set (match_operand:PSI 0 "mra_operand" "=RsiSd") [(set (match_operand:PSI 0 "mra_operand" "=RsiSd")
(mult:PSI (match_operand:PSI 1 "mra_operand" "%0") (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" "TARGET_A24"
"shl.l\t%b2,%0" "shl.l\t%b2,%0"
[(set_attr "flags" "szc")] [(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" (define_expand "divmodqi4"
......
...@@ -195,3 +195,8 @@ ...@@ -195,3 +195,8 @@
(ior (match_operand 0 "m32c_r0_operand") (ior (match_operand 0 "m32c_r0_operand")
(ior (match_operand 0 "m32c_mem0_operand") (ior (match_operand 0 "m32c_mem0_operand")
(match_code "parallel")))) (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\")")))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment