aboutsummaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorGeorg-Johann Lay <avr@gjlay.de>2011-11-01 14:10:13 +0000
committerGeorg-Johann Lay <avr@gjlay.de>2011-11-01 14:10:13 +0000
commit90b3f23e64ae8c4b7a3194d0d830f1191554cfd0 (patch)
tree64a7ad573ee0812364b547eb84d67b74032a6153 /gcc/config
parent27a70fa9bdcede800447dd56252a51b8ba51d9bb (diff)
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: https://gcc.gnu.org/svn/gcc/trunk@180739 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/avr/avr.c11
-rw-r--r--gcc/config/avr/avr.h2
-rw-r--r--gcc/config/avr/avr.md81
-rw-r--r--gcc/config/avr/avr.opt8
4 files changed, 86 insertions, 16 deletions
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 "<extend_u>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.