1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
2009-06-23 Kazu Hirata <kazu@codesourcery.com>
Issue #4613
gcc/
* config/arm/arm.c (arm_rtx_costs_1): Teach that the cost of MLS
is the same as its underlying multiplication.
* config/arm/arm.md (two splitters): New.
* config/arm/predicates.md (binary_operator): New.
2010-07-26 Julian Brown <julian@codesourcery.com>
Merge from Sourcery G++ 4.4:
2008-09-08 Daniel Jacobowitz <dan@codesourcery.com>
gcc/
=== modified file 'gcc/config/arm/arm.c'
--- old/gcc/config/arm/arm.c 2010-08-12 11:33:54 +0000
+++ new/gcc/config/arm/arm.c 2010-08-12 13:35:39 +0000
@@ -6604,6 +6604,19 @@
return true;
}
+ /* MLS is just as expensive as its underlying multiplication.
+ Exclude a shift by a constant, which is expressed as a
+ multiplication. */
+ if (TARGET_32BIT && arm_arch_thumb2
+ && GET_CODE (XEXP (x, 1)) == MULT
+ && ! (GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
+ && ((INTVAL (XEXP (XEXP (x, 1), 1)) &
+ (INTVAL (XEXP (XEXP (x, 1), 1)) - 1)) == 0)))
+ {
+ /* The cost comes from the cost of the multiply. */
+ return false;
+ }
+
/* Fall through */
case PLUS:
=== modified file 'gcc/config/arm/arm.md'
--- old/gcc/config/arm/arm.md 2010-08-12 11:33:54 +0000
+++ new/gcc/config/arm/arm.md 2010-08-12 13:35:39 +0000
@@ -1355,6 +1355,49 @@
(set_attr "predicable" "yes")]
)
+; The combiner cannot combine the first and last insns in the
+; following sequence because of the intervening insn, so help the
+; combiner with this splitter. The combiner does attempt to split
+; this particular combination but does not know this exact split.
+; Note that the combiner puts the constant at the outermost operation
+; as a part of canonicalization.
+;
+; mul r3, r2, r1
+; <add/sub> r3, r3, <constant>
+; add r3, r3, r4
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "plusminus_operator"
+ [(plus:SI (mult:SI (match_operand:SI 2 "s_register_operand" "")
+ (match_operand:SI 3 "s_register_operand" ""))
+ (match_operand:SI 4 "s_register_operand" ""))
+ (match_operand:SI 5 "arm_immediate_operand" "")]))]
+ "TARGET_32BIT"
+ [(set (match_dup 0)
+ (plus:SI (mult:SI (match_dup 2) (match_dup 3))
+ (match_dup 4)))
+ (set (match_dup 0)
+ (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
+ "")
+
+; Likewise for MLS. MLS is available only on select architectures.
+
+(define_split
+ [(set (match_operand:SI 0 "s_register_operand" "")
+ (match_operator:SI 1 "plusminus_operator"
+ [(minus:SI (match_operand:SI 2 "s_register_operand" "")
+ (mult:SI (match_operand:SI 3 "s_register_operand" "")
+ (match_operand:SI 4 "s_register_operand" "")))
+ (match_operand:SI 5 "arm_immediate_operand" "")]))]
+ "TARGET_32BIT && arm_arch_thumb2"
+ [(set (match_dup 0)
+ (minus:SI (match_dup 2)
+ (mult:SI (match_dup 3) (match_dup 4))))
+ (set (match_dup 0)
+ (match_op_dup:SI 1 [(match_dup 0) (match_dup 5)]))]
+ "")
+
(define_insn "*mulsi3addsi_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV
=== modified file 'gcc/config/arm/predicates.md'
--- old/gcc/config/arm/predicates.md 2010-08-10 13:31:21 +0000
+++ new/gcc/config/arm/predicates.md 2010-08-12 13:35:39 +0000
@@ -197,6 +197,11 @@
(and (match_code "plus,minus,ior,xor,and")
(match_test "mode == GET_MODE (op)")))
+;; True for plus/minus operators
+(define_special_predicate "plusminus_operator"
+ (and (match_code "plus,minus")
+ (match_test "mode == GET_MODE (op)")))
+
;; True for logical binary operators.
(define_special_predicate "logical_binary_operator"
(and (match_code "ior,xor,and")
|