aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-08-21 19:21:30 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1992-08-21 19:21:30 -0400
commit5a5064dcb35dced4e8e81d362a8086ad6cc617d8 (patch)
tree4de5a0e578751dec82ce7b923641cce56714b43a /gcc/optabs.c
parent2f9ba5a9a32a37740571bbd4ab2cf10b1411ef4e (diff)
downloadgcc-5a5064dcb35dced4e8e81d362a8086ad6cc617d8.zip
gcc-5a5064dcb35dced4e8e81d362a8086ad6cc617d8.tar.gz
gcc-5a5064dcb35dced4e8e81d362a8086ad6cc617d8.tar.bz2
(expand_binop): If, e.g., mulqi3 doesn't exist, try mulqihi3.
From-SVN: r1932
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index bdc69ca..cee0762 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -413,15 +413,39 @@ expand_binop (mode, binoptab, op0, op1, target, unsignedp, methods)
delete_insns_since (last);
}
+ /* If this is a multiply, see if we can do a widening operation that
+ takes operands of this mode and makes a wider mode. */
+
+ if (binoptab == smul_optab && GET_MODE_WIDER_MODE (mode) != VOIDmode
+ && (((unsignedp ? umul_widen_optab : smul_widen_optab)
+ ->handlers[(int) GET_MODE_WIDER_MODE (mode)].insn_code)
+ != CODE_FOR_nothing))
+ {
+ temp = expand_binop (GET_MODE_WIDER_MODE (mode),
+ unsignedp ? umul_widen_optab : smul_widen_optab,
+ op0, op1, 0, unsignedp, OPTAB_DIRECT);
+
+ if (GET_MODE_CLASS (mode) == MODE_INT)
+ return gen_lowpart (mode, temp);
+ else
+ return convert_to_mode (mode, temp, unsignedp);
+ }
+
/* Look for a wider mode of the same class for which we think we
- can open-code the operation. */
+ can open-code the operation. Check for a widening multiply at the
+ wider mode as well. */
if ((class == MODE_INT || class == MODE_FLOAT || class == MODE_COMPLEX_FLOAT)
&& mode != OPTAB_DIRECT && mode != OPTAB_LIB)
for (wider_mode = GET_MODE_WIDER_MODE (mode); wider_mode != VOIDmode;
wider_mode = GET_MODE_WIDER_MODE (wider_mode))
{
- if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing)
+ if (binoptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
+ || (binoptab == smul_optab
+ && GET_MODE_WIDER_MODE (wider_mode) != VOIDmode
+ && (((unsignedp ? umul_widen_optab : smul_widen_optab)
+ ->handlers[(int) GET_MODE_WIDER_MODE (wider_mode)].insn_code)
+ != CODE_FOR_nothing)))
{
rtx xop0 = op0, xop1 = op1;
int no_extend = 0;