From fd2db4d6d890a3119a88ad7b7dde3338193be276 Mon Sep 17 00:00:00 2001 From: gjl Date: Tue, 1 Nov 2011 14:10:13 +0000 Subject: PR target/50910 * config/avr/avr.opt (-mbranch-cost=): New option. * config/avr/avr.h (BRANCH_COST): Define to avr_branch_cost. * config/avr/avr.c (avr_rtx_costs_1): Adjust [U]DIV/[U]MOD costs. * config/avr/avr.md (*addqi3.lt0, *addhi3.lt0, *addsi3.lt0): New insns. (*addhi3_zero_extend1): Remov % in constraint of operand 1. (*addhi3.sign_extend1, *subhi3.sign_extend2): New insns. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180739 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++++++ gcc/config/avr/avr.c | 11 +++++-- gcc/config/avr/avr.h | 2 +- gcc/config/avr/avr.md | 81 ++++++++++++++++++++++++++++++++++++++++++-------- gcc/config/avr/avr.opt | 8 +++++ 5 files changed, 96 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index af01b0e7f94..d8476c27c6b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2011-11-01 Georg-Johann Lay + + PR target/50910 + * config/avr/avr.opt (-mbranch-cost=): New option. + * config/avr/avr.h (BRANCH_COST): Define to avr_branch_cost. + * config/avr/avr.c (avr_rtx_costs_1): Adjust [U]DIV/[U]MOD costs. + * config/avr/avr.md (*addqi3.lt0, *addhi3.lt0, *addsi3.lt0): New insns. + (*addhi3_zero_extend1): Remov % in constraint of operand 1. + (*addhi3.sign_extend1, *subhi3.sign_extend2): New insns. + 2011-11-01 Tom de Vries PR tree-optimization/50908 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 187dcb14912..6435c4854f5 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -6477,11 +6477,16 @@ avr_rtx_costs_1 (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED, case UDIV: case UMOD: if (!speed) - *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); + *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); else - return false; + *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode)); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); + /* For div/mod with const-int divisor we have at least the cost of + loading the divisor. */ + if (CONST_INT_P (XEXP (x, 1))) + *total += COSTS_N_INSNS (GET_MODE_SIZE (mode)); + /* Add some overall penaly for clobbering and moving around registers */ + *total += COSTS_N_INSNS (2); return true; case ROTATE: diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h index 50f64884c07..47ca8ff759a 100644 --- a/gcc/config/avr/avr.h +++ b/gcc/config/avr/avr.h @@ -385,7 +385,7 @@ typedef struct avr_args { } \ } while (0) -#define BRANCH_COST(speed_p, predictable_p) 0 +#define BRANCH_COST(speed_p, predictable_p) avr_branch_cost #define SLOW_BYTE_ACCESS 0 diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index faf18797bc1..f3edbbcd026 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -776,27 +776,36 @@ (define_insn "*addhi3_zero_extend" - [(set (match_operand:HI 0 "register_operand" "=r") - (plus:HI (zero_extend:HI - (match_operand:QI 1 "register_operand" "r")) - (match_operand:HI 2 "register_operand" "0")))] + [(set (match_operand:HI 0 "register_operand" "=r") + (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "r")) + (match_operand:HI 2 "register_operand" "0")))] "" - "add %A0,%1 - adc %B0,__zero_reg__" + "add %A0,%1\;adc %B0,__zero_reg__" [(set_attr "length" "2") (set_attr "cc" "set_n")]) (define_insn "*addhi3_zero_extend1" - [(set (match_operand:HI 0 "register_operand" "=r") - (plus:HI (match_operand:HI 1 "register_operand" "%0") - (zero_extend:HI - (match_operand:QI 2 "register_operand" "r"))))] + [(set (match_operand:HI 0 "register_operand" "=r") + (plus:HI (match_operand:HI 1 "register_operand" "0") + (zero_extend:HI (match_operand:QI 2 "register_operand" "r"))))] "" - "add %A0,%2 - adc %B0,__zero_reg__" + "add %A0,%2\;adc %B0,__zero_reg__" [(set_attr "length" "2") (set_attr "cc" "set_n")]) +(define_insn "*addhi3.sign_extend1" + [(set (match_operand:HI 0 "register_operand" "=r") + (plus:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "r")) + (match_operand:HI 2 "register_operand" "0")))] + "" + { + return reg_overlap_mentioned_p (operands[0], operands[1]) + ? "mov __tmp_reg__,%1\;add %A0,%1\;adc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;dec %B0" + : "add %A0,%1\;adc %B0,__zero_reg__\;sbrc %1,7\;dec %B0"; + } + [(set_attr "length" "5") + (set_attr "cc" "clobber")]) + (define_insn "*addhi3_sp" [(set (match_operand:HI 1 "stack_register_operand" "=q") (plus:HI (match_operand:HI 2 "stack_register_operand" "q") @@ -956,6 +965,19 @@ [(set_attr "length" "2") (set_attr "cc" "set_czn")]) +(define_insn "*subhi3.sign_extend2" + [(set (match_operand:HI 0 "register_operand" "=r") + (minus:HI (match_operand:HI 1 "register_operand" "0") + (sign_extend:HI (match_operand:QI 2 "register_operand" "r"))))] + "" + { + return reg_overlap_mentioned_p (operands[0], operands[2]) + ? "mov __tmp_reg__,%2\;sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc __tmp_reg__,7\;inc %B0" + : "sub %A0,%2\;sbc %B0,__zero_reg__\;sbrc %2,7\;inc %B0"; + } + [(set_attr "length" "5") + (set_attr "cc" "clobber")]) + (define_insn "subsi3" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (match_operand:SI 1 "register_operand" "0") @@ -1054,6 +1076,41 @@ [(set_attr "length" "2") (set_attr "cc" "clobber")]) +(define_insn "*addqi3.lt0" + [(set (match_operand:QI 0 "register_operand" "=r") + (plus:QI (lt:QI (match_operand:QI 1 "register_operand" "r") + (const_int 0)) + (match_operand:QI 2 "register_operand" "0")))] + "" + "sbrc %1,7\;inc %0" + [(set_attr "length" "2") + (set_attr "cc" "clobber")]) + +(define_insn "*addhi3.lt0" + [(set (match_operand:HI 0 "register_operand" "=w,r") + (plus:HI (lt:HI (match_operand:QI 1 "register_operand" "r,r") + (const_int 0)) + (match_operand:HI 2 "register_operand" "0,0"))) + (clobber (match_scratch:QI 3 "=X,&1"))] + "" + "@ + sbrc %1,7\;adiw %0,1 + lsl %1\;adc %A0,__zero_reg__\;adc %B0,__zero_reg__" + [(set_attr "length" "2,3") + (set_attr "cc" "clobber")]) + +(define_insn "*addsi3.lt0" + [(set (match_operand:SI 0 "register_operand" "=r") + (plus:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "r") + (const_int 31)) + (match_operand:SI 2 "register_operand" "0")))] + "" + "mov __tmp_reg__,%D1\;lsl __tmp_reg__ + adc %A0,__zero_reg__\;adc %B0,__zero_reg__\;adc %C0,__zero_reg__\;adc %D0,__zero_reg__" + [(set_attr "length" "6") + (set_attr "cc" "clobber")]) + + ;; "umulqihi3" ;; "mulqihi3" (define_insn "mulqihi3" diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt index 8de929d1291..bb9c90ec36f 100644 --- a/gcc/config/avr/avr.opt +++ b/gcc/config/avr/avr.opt @@ -40,6 +40,10 @@ mno-interrupts Target Report RejectNegative Mask(NO_INTERRUPTS) Change the stack pointer without disabling interrupts +mbranch-cost= +Target Report Joined RejectNegative UInteger Var(avr_branch_cost) Init(0) +Set the branch costs for conditional branch instructions. Reasonable values are small, non-negative integers. The default branch cost is 0. + morder1 Target Report Undocumented Mask(ORDER_1) @@ -69,3 +73,7 @@ Accumulate outgoing function arguments and acquire/release the needed stack spac mstrict-X Target Report Var(avr_strict_X) Init(0) When accessing RAM, use X as imposed by the hardware, i.e. just use pre-decrement, post-increment and indirect addressing with the X register. Without this option, the compiler may assume that there is an addressing mode X+const similar to Y+const and Z+const and emit instructions to emulate such an addressing mode for X. + +mbranch-cost= +Target Report RejectNegative Joined UInteger Var(avr_branch_cost) Init(0) +Set the cost of a branch instruction. Default value is 0. -- cgit v1.2.1