Commit 8c352fa8 by Georg-Johann Lay Committed by Georg-Johann Lay

re PR target/36467 ([avr] Missed optimization with pointer arithmetic and mul*)


	PR target/36467
	PR target/49687
	* config/avr/avr.md (mulhi3): Use register_or_s9_operand for
	operand2 and expand appropriately if there is a CONST_INT in
	operand2.
	(usmulqihi3): New insn.
	(*sumulqihi3): New insn.
	(*osmulqihi3): New insn.
	(*oumulqihi3): New insn.
	(*muluqihi3.uconst): New insn_and_split.
	(*muluqihi3.sconst): New insn_and_split.
	(*mulsqihi3.sconst): New insn_and_split.
	(*mulsqihi3.uconst): New insn_and_split.
	(*mulsqihi3.oconst): New insn_and_split.
	(*ashifthi3.signx.const): New insn_and_split.
	(*ashifthi3.signx.const7): New insn_and_split.
	(*ashifthi3.zerox.const): New insn_and_split.
	(mulsqihi3): New insn.
	(muluqihi3): New insn.
	(muloqihi3): New insn.
	* config/avr/predicates.md (const_2_to_7_operand): New.
	(const_2_to_6_operand): New.
	(u8_operand): New.
	(s8_operand): New.
	(o8_operand): New.
	(s9_operand): New.
	(register_or_s9_operand): New.

From-SVN: r176527
parent be31603a
2011-07-20 Georg-Johann Lay <avr@gjlay.de>
PR target/36467
PR target/49687
* config/avr/avr.md (mulhi3): Use register_or_s9_operand for
operand2 and expand appropriately if there is a CONST_INT in
operand2.
(usmulqihi3): New insn.
(*sumulqihi3): New insn.
(*osmulqihi3): New insn.
(*oumulqihi3): New insn.
(*muluqihi3.uconst): New insn_and_split.
(*muluqihi3.sconst): New insn_and_split.
(*mulsqihi3.sconst): New insn_and_split.
(*mulsqihi3.uconst): New insn_and_split.
(*mulsqihi3.oconst): New insn_and_split.
(*ashifthi3.signx.const): New insn_and_split.
(*ashifthi3.signx.const7): New insn_and_split.
(*ashifthi3.zerox.const): New insn_and_split.
(mulsqihi3): New insn.
(muluqihi3): New insn.
(muloqihi3): New insn.
* config/avr/predicates.md (const_2_to_7_operand): New.
(const_2_to_6_operand): New.
(u8_operand): New.
(s8_operand): New.
(o8_operand): New.
(s9_operand): New.
(register_or_s9_operand): New.
2011-07-20 Kai Tietz <ktietz@redhat.com>
* builtins.c (fold_builtin_expect): See through the cast
......
......@@ -5464,7 +5464,42 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
case HImode:
if (AVR_HAVE_MUL)
*total = COSTS_N_INSNS (!speed ? 7 : 10);
{
rtx op0 = XEXP (x, 0);
rtx op1 = XEXP (x, 1);
enum rtx_code code0 = GET_CODE (op0);
enum rtx_code code1 = GET_CODE (op1);
bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
if (ex0
&& (u8_operand (op1, HImode)
|| s8_operand (op1, HImode)))
{
*total = COSTS_N_INSNS (!speed ? 4 : 6);
return true;
}
if (ex0
&& register_operand (op1, HImode))
{
*total = COSTS_N_INSNS (!speed ? 5 : 8);
return true;
}
else if (ex0 || ex1)
{
*total = COSTS_N_INSNS (!speed ? 3 : 5);
return true;
}
else if (register_operand (op0, HImode)
&& (u8_operand (op1, HImode)
|| s8_operand (op1, HImode)))
{
*total = COSTS_N_INSNS (!speed ? 6 : 9);
return true;
}
else
*total = COSTS_N_INSNS (!speed ? 7 : 10);
}
else if (!speed)
*total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
else
......@@ -5547,6 +5582,17 @@ avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, int *total,
break;
case HImode:
if (AVR_HAVE_MUL)
{
if (const_2_to_7_operand (XEXP (x, 1), HImode)
&& (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
|| ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
{
*total = COSTS_N_INSNS (!speed ? 4 : 6);
return true;
}
}
if (GET_CODE (XEXP (x, 1)) != CONST_INT)
{
*total = COSTS_N_INSNS (!speed ? 5 : 41);
......
......@@ -73,6 +73,16 @@
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 7)")))
;; Return 1 if OP is constant integer 2..7 for MODE.
(define_predicate "const_2_to_7_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 2, 7)")))
;; Return 1 if OP is constant integer 2..6 for MODE.
(define_predicate "const_2_to_6_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 2, 6)")))
;; Returns true if OP is either the constant zero or a register.
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "register_operand")
......@@ -156,3 +166,26 @@
(and (match_code "const_int")
(match_test "8 == INTVAL(op) || 16 == INTVAL(op) || 24 == INTVAL(op)")))
;; Unsigned CONST_INT that fits in 8 bits, i.e. 0..255.
(define_predicate "u8_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 255)")))
;; Signed CONST_INT that fits in 8 bits, i.e. -128..127.
(define_predicate "s8_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -128, 127)")))
;; One-extended CONST_INT that fits in 8 bits, i.e. -256..-1.
(define_predicate "o8_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -256, -1)")))
;; Signed CONST_INT that fits in 9 bits, i.e. -256..255.
(define_predicate "s9_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), -256, 255)")))
(define_predicate "register_or_s9_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "s9_operand")))
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