From b10af0c8206f7ff2aefd13b3d7d20accf4c9a33c Mon Sep 17 00:00:00 2001 From: Torbjorn Granlund Date: Sun, 17 Dec 1995 16:39:58 +0000 Subject: [PATCH] (expand_expr... (expand_expr, case MULT_EXPR): Generalize code for widening multiply to handle signed widening multiply when only unsigned optab is defined, and vice versa. From-SVN: r10788 --- gcc/expr.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/gcc/expr.c b/gcc/expr.c index b7860c0dbcd..5297ae21694 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -5430,20 +5430,46 @@ expand_expr (exp, target, tmode, modifier) { enum machine_mode innermode = TYPE_MODE (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))); + optab other_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) + ? smul_widen_optab : umul_widen_optab); this_optab = (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (exp, 0), 0))) ? umul_widen_optab : smul_widen_optab); - if (mode == GET_MODE_WIDER_MODE (innermode) - && this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) + if (mode == GET_MODE_WIDER_MODE (innermode)) { - op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), - NULL_RTX, VOIDmode, 0); - if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) - op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, - VOIDmode, 0); - else - op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), - NULL_RTX, VOIDmode, 0); - goto binop2; + if (this_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing) + { + op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), + NULL_RTX, VOIDmode, 0); + if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) + op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, + VOIDmode, 0); + else + op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), + NULL_RTX, VOIDmode, 0); + goto binop2; + } + else if (other_optab->handlers[(int) mode].insn_code != CODE_FOR_nothing + && innermode == word_mode) + { + rtx htem; + op0 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 0), 0), + NULL_RTX, VOIDmode, 0); + if (TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) + op1 = expand_expr (TREE_OPERAND (exp, 1), NULL_RTX, + VOIDmode, 0); + else + op1 = expand_expr (TREE_OPERAND (TREE_OPERAND (exp, 1), 0), + NULL_RTX, VOIDmode, 0); + temp = expand_binop (mode, other_optab, op0, op1, target, + unsignedp, OPTAB_LIB_WIDEN); + htem = expand_mult_highpart_adjust (innermode, + gen_highpart (innermode, temp), + op0, op1, + gen_highpart (innermode, temp), + unsignedp); + emit_move_insn (gen_highpart (innermode, temp), htem); + return temp; + } } } op0 = expand_expr (TREE_OPERAND (exp, 0), subtarget, VOIDmode, 0); -- 2.30.2