Commit 296799ba by Georg-Johann Lay Committed by Georg-Johann Lay

re PR target/49687 ([avr] Missed optimization for widening MUL)

	
	PR target/49687
	* config/avr/t-avr (LIB1ASMFUNCS): Remove _xmulhisi3_exit.
	Add _muluhisi3, _mulshisi3, _usmulhisi3.
	* config/avr/libgcc.S (__mulsi3): Rewrite.
	(__mulhisi3): Rewrite.
	(__umulhisi3): Rewrite.
	(__usmulhisi3): New.
	(__muluhisi3): New.
	(__mulshisi3): New.
	(__mulohisi3): New.
	(__mulqi3, __mulqihi3, __umulqihi3, __mulhi3): Use DEFUN/ENDF to
	declare.
	* config/avr/predicates.md (pseudo_register_operand): Rewrite.
	(pseudo_register_or_const_int_operand): New.
	(combine_pseudo_register_operand): New.
	(u16_operand): New.
	(s16_operand): New.
	(o16_operand): New.
	* config/avr/avr.c (avr_rtx_costs): Handle costs for mult:SI.
	* config/avr/avr.md (QIHI, QIHI2): New mode iterators.
	(any_extend, any_extend2): New code iterators.
	(extend_prefix): New code attribute.
	(mulsi3): Rewrite. Turn insn to expander.
	(mulhisi3): Ditto.
	(umulhisi3): Ditto.
	(usmulhisi3): New expander.
	(*mulsi3): New insn-and-split.
	(mulu<mode>si3): New insn-and-split.
	(muls<mode>si3): New insn-and-split.
	(mulohisi3): New insn-and-split.
	(*uumulqihisi3, *uumulhiqisi3, *uumulhihisi3, *uumulqiqisi3,
	*usmulqihisi3, *usmulhiqisi3, *usmulhihisi3, *usmulqiqisi3,
	*sumulqihisi3, *sumulhiqisi3, *sumulhihisi3, *sumulqiqisi3,
	*ssmulqihisi3, *ssmulhiqisi3, *ssmulhihisi3, *ssmulqiqisi3): New
	insn-and-split.
	(*mulsi3_call): Rewrite.
	(*mulhisi3_call): Rewrite.
	(*umulhisi3_call): Rewrite.
	(*usmulhisi3_call): New insn.
	(*muluhisi3_call): New insn.
	(*mulshisi3_call): New insn.
	(*mulohisi3_call): New insn.
	(extendqihi2): Use combine_pseudo_register_operand as predicate
	for operand 1.
	(extendqisi2): Ditto.
	(zero_extendqihi2): Ditto.
	(zero_extendqisi2): Ditto.
	(zero_extendhisi2): Ditto.
	(extendhisi2): Ditto. Don't early-clobber operand 0.

From-SVN: r176862
parent 2374a88a
2011-07-28 Georg-Johann Lay <avr@gjlay.de>
PR target/49687
* config/avr/t-avr (LIB1ASMFUNCS): Remove _xmulhisi3_exit.
Add _muluhisi3, _mulshisi3, _usmulhisi3.
* config/avr/libgcc.S (__mulsi3): Rewrite.
(__mulhisi3): Rewrite.
(__umulhisi3): Rewrite.
(__usmulhisi3): New.
(__muluhisi3): New.
(__mulshisi3): New.
(__mulohisi3): New.
(__mulqi3, __mulqihi3, __umulqihi3, __mulhi3): Use DEFUN/ENDF to
declare.
* config/avr/predicates.md (pseudo_register_operand): Rewrite.
(pseudo_register_or_const_int_operand): New.
(combine_pseudo_register_operand): New.
(u16_operand): New.
(s16_operand): New.
(o16_operand): New.
* config/avr/avr.c (avr_rtx_costs): Handle costs for mult:SI.
* config/avr/avr.md (QIHI, QIHI2): New mode iterators.
(any_extend, any_extend2): New code iterators.
(extend_prefix): New code attribute.
(mulsi3): Rewrite. Turn insn to expander.
(mulhisi3): Ditto.
(umulhisi3): Ditto.
(usmulhisi3): New expander.
(*mulsi3): New insn-and-split.
(mulu<mode>si3): New insn-and-split.
(muls<mode>si3): New insn-and-split.
(mulohisi3): New insn-and-split.
(*uumulqihisi3, *uumulhiqisi3, *uumulhihisi3, *uumulqiqisi3,
*usmulqihisi3, *usmulhiqisi3, *usmulhihisi3, *usmulqiqisi3,
*sumulqihisi3, *sumulhiqisi3, *sumulhihisi3, *sumulqiqisi3,
*ssmulqihisi3, *ssmulhiqisi3, *ssmulhihisi3, *ssmulqiqisi3): New
insn-and-split.
(*mulsi3_call): Rewrite.
(*mulhisi3_call): Rewrite.
(*umulhisi3_call): Rewrite.
(*usmulhisi3_call): New insn.
(*muluhisi3_call): New insn.
(*mulshisi3_call): New insn.
(*mulohisi3_call): New insn.
(extendqihi2): Use combine_pseudo_register_operand as predicate
for operand 1.
(extendqisi2): Ditto.
(zero_extendqihi2): Ditto.
(zero_extendqisi2): Ditto.
(zero_extendhisi2): Ditto.
(extendhisi2): Ditto. Don't early-clobber operand 0.
2011-07-28 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.c (add->lea splitter): Add SWI mode to PLUS RTX.
......
......@@ -5515,6 +5515,34 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
return false;
break;
case SImode:
if (AVR_HAVE_MUL)
{
if (!speed)
{
/* Add some additional costs besides CALL like moves etc. */
*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
}
else
{
/* Just a rough estimate. Even with -O2 we don't want bulky
code expanded inline. */
*total = COSTS_N_INSNS (25);
}
}
else
{
if (speed)
*total = COSTS_N_INSNS (300);
else
/* Add some additional costs besides CALL like moves etc. */
*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
}
return true;
default:
return false;
}
......
......@@ -155,10 +155,34 @@
(ior (match_test "register_operand (XEXP (op, 0), mode)")
(match_test "CONSTANT_ADDRESS_P (XEXP (op, 0))"))))
;; For some insns we must ensure that no hard register is inserted
;; into their operands because the insns are split and the split
;; involves hard registers. An example are divmod insn that are
;; split to insns that represent implicit library calls.
;; True for register that is pseudo register.
(define_predicate "pseudo_register_operand"
(and (match_code "reg")
(match_test "!HARD_REGISTER_P (op)")))
(and (match_operand 0 "register_operand")
(not (and (match_code "reg")
(match_test "HARD_REGISTER_P (op)")))))
;; True for operand that is pseudo register or CONST_INT.
(define_predicate "pseudo_register_or_const_int_operand"
(ior (match_operand 0 "const_int_operand")
(match_operand 0 "pseudo_register_operand")))
;; We keep combiner from inserting hard registers into the input of sign- and
;; zero-extends. A hard register in the input operand is not wanted because
;; 32-bit multiply patterns clobber some hard registers and extends with a
;; hard register that overlaps these clobbers won't combine to a widening
;; multiplication. There is no need for combine to propagate or insert
;; hard registers, register allocation can do it just as well.
;; True for operand that is pseudo register at combine time.
(define_predicate "combine_pseudo_register_operand"
(ior (match_operand 0 "pseudo_register_operand")
(and (match_operand 0 "register_operand")
(match_test "reload_completed || reload_in_progress"))))
;; Return true if OP is a constant integer that is either
;; 8 or 16 or 24.
......@@ -189,3 +213,18 @@
(define_predicate "register_or_s9_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "s9_operand")))
;; Unsigned CONST_INT that fits in 16 bits, i.e. 0..65536.
(define_predicate "u16_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, (1<<16)-1)")))
;; Signed CONST_INT that fits in 16 bits, i.e. -32768..32767.
(define_predicate "s16_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -(1<<15), (1<<15)-1)")))
;; One-extended CONST_INT that fits in 16 bits, i.e. -65536..-1.
(define_predicate "o16_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -(1<<16), -1)")))
......@@ -41,7 +41,9 @@ LIB1ASMFUNCS = \
_mulhi3 \
_mulhisi3 \
_umulhisi3 \
_xmulhisi3_exit \
_usmulhisi3 \
_muluhisi3 \
_mulshisi3 \
_mulsi3 \
_udivmodqi4 \
_divmodqi4 \
......
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