summaryrefslogtreecommitdiff
path: root/gcc/config/m32c/m32c.c
diff options
context:
space:
mode:
authordj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-16 01:31:39 +0000
committerdj <dj@138bc75d-0d04-0410-961f-82ee72b054a4>2005-12-16 01:31:39 +0000
commitc47b86425e4c37be4d2d73d8781bd8cb2424af0f (patch)
treed42ce2ab6f459bf43ed2bd447cfcde5d0656e0fe /gcc/config/m32c/m32c.c
parent449d37610c15b7f7fba80fdc301136fae951741a (diff)
downloadgcc-c47b86425e4c37be4d2d73d8781bd8cb2424af0f.tar.gz
* 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
Diffstat (limited to 'gcc/config/m32c/m32c.c')
-rw-r--r--gcc/config/m32c/m32c.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c
index 97b095328e4..8580922a402 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