]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/ldrdstrd.md
AArch64: Fix initializer for array so it's a C initializer instead of C++.
[thirdparty/gcc.git] / gcc / config / arm / ldrdstrd.md
CommitLineData
4542a38a
GY
1;; ARM ldrd/strd peephole optimizations.
2;;
a5544970 3;; Copyright (C) 2013-2019 Free Software Foundation, Inc.
4542a38a
GY
4;;
5;; Written by Greta Yorsh <greta.yorsh@arm.com>
6
7;; This file is part of GCC.
8;;
9;; GCC is free software; you can redistribute it and/or modify it
10;; under the terms of the GNU General Public License as published by
11;; the Free Software Foundation; either version 3, or (at your option)
12;; any later version.
13;;
14;; GCC is distributed in the hope that it will be useful, but
15;; WITHOUT ANY WARRANTY; without even the implied warranty of
16;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17;; General Public License for more details.
18;;
19;; You should have received a copy of the GNU General Public License
20;; along with GCC; see the file COPYING3. If not see
21;; <http://www.gnu.org/licenses/>.
22
23;; The following peephole optimizations identify consecutive memory
24;; accesses, and try to rearrange the operands to enable generation of
25;; ldrd/strd.
26
27(define_peephole2 ; ldrd
28 [(set (match_operand:SI 0 "arm_general_register_operand" "")
29 (match_operand:SI 2 "memory_operand" ""))
30 (set (match_operand:SI 1 "arm_general_register_operand" "")
31 (match_operand:SI 3 "memory_operand" ""))]
2fe37211 32 "TARGET_LDRD"
4542a38a
GY
33 [(const_int 0)]
34{
35 if (!gen_operands_ldrd_strd (operands, true, false, false))
36 FAIL;
37 else if (TARGET_ARM)
38 {
39 /* In ARM state, the destination registers of LDRD/STRD must be
40 consecutive. We emit DImode access. */
41 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
42 operands[2] = adjust_address (operands[2], DImode, 0);
43 /* Emit [(set (match_dup 0) (match_dup 2))] */
f7df4a84 44 emit_insn (gen_rtx_SET (operands[0], operands[2]));
4542a38a
GY
45 DONE;
46 }
47 else if (TARGET_THUMB2)
48 {
49 /* Emit the pattern:
50 [(parallel [(set (match_dup 0) (match_dup 2))
51 (set (match_dup 1) (match_dup 3))])] */
f7df4a84
RS
52 rtx t1 = gen_rtx_SET (operands[0], operands[2]);
53 rtx t2 = gen_rtx_SET (operands[1], operands[3]);
4542a38a
GY
54 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2)));
55 DONE;
56 }
57})
58
59(define_peephole2 ; strd
60 [(set (match_operand:SI 2 "memory_operand" "")
61 (match_operand:SI 0 "arm_general_register_operand" ""))
62 (set (match_operand:SI 3 "memory_operand" "")
63 (match_operand:SI 1 "arm_general_register_operand" ""))]
2fe37211 64 "TARGET_LDRD"
4542a38a
GY
65 [(const_int 0)]
66{
67 if (!gen_operands_ldrd_strd (operands, false, false, false))
68 FAIL;
69 else if (TARGET_ARM)
70 {
71 /* In ARM state, the destination registers of LDRD/STRD must be
72 consecutive. We emit DImode access. */
73 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
74 operands[2] = adjust_address (operands[2], DImode, 0);
75 /* Emit [(set (match_dup 2) (match_dup 0))] */
f7df4a84 76 emit_insn (gen_rtx_SET (operands[2], operands[0]));
4542a38a
GY
77 DONE;
78 }
79 else if (TARGET_THUMB2)
80 {
81 /* Emit the pattern:
82 [(parallel [(set (match_dup 2) (match_dup 0))
83 (set (match_dup 3) (match_dup 1))])] */
f7df4a84
RS
84 rtx t1 = gen_rtx_SET (operands[2], operands[0]);
85 rtx t2 = gen_rtx_SET (operands[3], operands[1]);
4542a38a
GY
86 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2)));
87 DONE;
88 }
89})
90
91;; The following peepholes reorder registers to enable LDRD/STRD.
92(define_peephole2 ; strd of constants
93 [(set (match_operand:SI 0 "arm_general_register_operand" "")
94 (match_operand:SI 4 "const_int_operand" ""))
95 (set (match_operand:SI 2 "memory_operand" "")
96 (match_dup 0))
97 (set (match_operand:SI 1 "arm_general_register_operand" "")
98 (match_operand:SI 5 "const_int_operand" ""))
99 (set (match_operand:SI 3 "memory_operand" "")
100 (match_dup 1))]
2fe37211 101 "TARGET_LDRD"
4542a38a
GY
102 [(const_int 0)]
103{
104 if (!gen_operands_ldrd_strd (operands, false, true, false))
105 FAIL;
106 else if (TARGET_ARM)
107 {
108 rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0]));
109 operands[2] = adjust_address (operands[2], DImode, 0);
110 /* Emit the pattern:
111 [(set (match_dup 0) (match_dup 4))
112 (set (match_dup 1) (match_dup 5))
113 (set (match_dup 2) tmp)] */
f7df4a84
RS
114 emit_insn (gen_rtx_SET (operands[0], operands[4]));
115 emit_insn (gen_rtx_SET (operands[1], operands[5]));
116 emit_insn (gen_rtx_SET (operands[2], tmp));
4542a38a
GY
117 DONE;
118 }
119 else if (TARGET_THUMB2)
120 {
121 /* Emit the pattern:
122 [(set (match_dup 0) (match_dup 4))
123 (set (match_dup 1) (match_dup 5))
124 (parallel [(set (match_dup 2) (match_dup 0))
125 (set (match_dup 3) (match_dup 1))])] */
f7df4a84
RS
126 emit_insn (gen_rtx_SET (operands[0], operands[4]));
127 emit_insn (gen_rtx_SET (operands[1], operands[5]));
128 rtx t1 = gen_rtx_SET (operands[2], operands[0]);
129 rtx t2 = gen_rtx_SET (operands[3], operands[1]);
4542a38a
GY
130 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2)));
131 DONE;
132 }
133})
134
135(define_peephole2 ; strd of constants
136 [(set (match_operand:SI 0 "arm_general_register_operand" "")
137 (match_operand:SI 4 "const_int_operand" ""))
138 (set (match_operand:SI 1 "arm_general_register_operand" "")
139 (match_operand:SI 5 "const_int_operand" ""))
140 (set (match_operand:SI 2 "memory_operand" "")
141 (match_dup 0))
142 (set (match_operand:SI 3 "memory_operand" "")
143 (match_dup 1))]
2fe37211
BE
144 "TARGET_LDRD"
145 [(const_int 0)]
4542a38a
GY
146{
147 if (!gen_operands_ldrd_strd (operands, false, true, false))
148 FAIL;
149 else if (TARGET_ARM)
150 {
151 rtx tmp = gen_rtx_REG (DImode, REGNO (operands[0]));
152 operands[2] = adjust_address (operands[2], DImode, 0);
153 /* Emit the pattern
154 [(set (match_dup 0) (match_dup 4))
155 (set (match_dup 1) (match_dup 5))
156 (set (match_dup 2) tmp)] */
f7df4a84
RS
157 emit_insn (gen_rtx_SET (operands[0], operands[4]));
158 emit_insn (gen_rtx_SET (operands[1], operands[5]));
159 emit_insn (gen_rtx_SET (operands[2], tmp));
4542a38a
GY
160 DONE;
161 }
162 else if (TARGET_THUMB2)
163 {
164 /* Emit the pattern:
165 [(set (match_dup 0) (match_dup 4))
166 (set (match_dup 1) (match_dup 5))
167 (parallel [(set (match_dup 2) (match_dup 0))
168 (set (match_dup 3) (match_dup 1))])] */
f7df4a84
RS
169 emit_insn (gen_rtx_SET (operands[0], operands[4]));
170 emit_insn (gen_rtx_SET (operands[1], operands[5]));
171 rtx t1 = gen_rtx_SET (operands[2], operands[0]);
172 rtx t2 = gen_rtx_SET (operands[3], operands[1]);
4542a38a
GY
173 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2)));
174 DONE;
175 }
176})
177
178;; The following two peephole optimizations are only relevant for ARM
179;; mode where LDRD/STRD require consecutive registers.
180
181(define_peephole2 ; swap the destination registers of two loads
182 ; before a commutative operation.
183 [(set (match_operand:SI 0 "arm_general_register_operand" "")
184 (match_operand:SI 2 "memory_operand" ""))
185 (set (match_operand:SI 1 "arm_general_register_operand" "")
186 (match_operand:SI 3 "memory_operand" ""))
187 (set (match_operand:SI 4 "arm_general_register_operand" "")
188 (match_operator:SI 5 "commutative_binary_operator"
189 [(match_operand 6 "arm_general_register_operand" "")
190 (match_operand 7 "arm_general_register_operand" "") ]))]
191 "TARGET_LDRD && TARGET_ARM
4542a38a
GY
192 && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7])))
193 ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6]))))
194 && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4]))
195 && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))"
196 [(set (match_dup 0) (match_dup 2))
197 (set (match_dup 4) (match_op_dup 5 [(match_dup 6) (match_dup 7)]))]
198 {
199 if (!gen_operands_ldrd_strd (operands, true, false, true))
200 {
201 FAIL;
202 }
203 else
204 {
205 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
206 operands[2] = adjust_address (operands[2], DImode, 0);
207 }
208 }
209)
210
211(define_peephole2 ; swap the destination registers of two loads
212 ; before a commutative operation that sets the flags.
213 [(set (match_operand:SI 0 "arm_general_register_operand" "")
214 (match_operand:SI 2 "memory_operand" ""))
215 (set (match_operand:SI 1 "arm_general_register_operand" "")
216 (match_operand:SI 3 "memory_operand" ""))
217 (parallel
218 [(set (match_operand:SI 4 "arm_general_register_operand" "")
219 (match_operator:SI 5 "commutative_binary_operator"
220 [(match_operand 6 "arm_general_register_operand" "")
221 (match_operand 7 "arm_general_register_operand" "") ]))
222 (clobber (reg:CC CC_REGNUM))])]
223 "TARGET_LDRD && TARGET_ARM
4542a38a
GY
224 && ( ((rtx_equal_p(operands[0], operands[6])) && (rtx_equal_p(operands[1], operands[7])))
225 ||((rtx_equal_p(operands[0], operands[7])) && (rtx_equal_p(operands[1], operands[6]))))
226 && (peep2_reg_dead_p (3, operands[0]) || rtx_equal_p (operands[0], operands[4]))
227 && (peep2_reg_dead_p (3, operands[1]) || rtx_equal_p (operands[1], operands[4]))"
228 [(set (match_dup 0) (match_dup 2))
229 (parallel
230 [(set (match_dup 4)
231 (match_op_dup 5 [(match_dup 6) (match_dup 7)]))
232 (clobber (reg:CC CC_REGNUM))])]
233 {
234 if (!gen_operands_ldrd_strd (operands, true, false, true))
235 {
236 FAIL;
237 }
238 else
239 {
240 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
241 operands[2] = adjust_address (operands[2], DImode, 0);
242 }
243 }
244)
245
246;; TODO: Handle LDRD/STRD with writeback:
247;; (a) memory operands can be POST_INC, POST_DEC, PRE_MODIFY, POST_MODIFY
248;; (b) Patterns may be followed by an update of the base address.