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:
parent
6cb8c05915
commit
12ea2512c4
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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\")")))
|
||||
|
|
Loading…
Reference in New Issue