]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/config/aarch64/aarch64-ldpstp.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / aarch64 / aarch64-ldpstp.md
1 ;; AArch64 ldp/stp peephole optimizations.
2 ;; Copyright (C) 2014-2022 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
4 ;;
5 ;; This file is part of GCC.
6 ;;
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
10 ;; any later version.
11 ;;
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
16 ;;
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
20
21 (define_peephole2
22 [(set (match_operand:GPI 0 "register_operand" "")
23 (match_operand:GPI 1 "memory_operand" ""))
24 (set (match_operand:GPI 2 "register_operand" "")
25 (match_operand:GPI 3 "memory_operand" ""))]
26 "aarch64_operands_ok_for_ldpstp (operands, true, <MODE>mode)"
27 [(parallel [(set (match_dup 0) (match_dup 1))
28 (set (match_dup 2) (match_dup 3))])]
29 {
30 aarch64_swap_ldrstr_operands (operands, true);
31 })
32
33 (define_peephole2
34 [(set (match_operand:GPI 0 "memory_operand" "")
35 (match_operand:GPI 1 "aarch64_reg_or_zero" ""))
36 (set (match_operand:GPI 2 "memory_operand" "")
37 (match_operand:GPI 3 "aarch64_reg_or_zero" ""))]
38 "aarch64_operands_ok_for_ldpstp (operands, false, <MODE>mode)"
39 [(parallel [(set (match_dup 0) (match_dup 1))
40 (set (match_dup 2) (match_dup 3))])]
41 {
42 aarch64_swap_ldrstr_operands (operands, false);
43 })
44
45 (define_peephole2
46 [(set (match_operand:GPF 0 "register_operand" "")
47 (match_operand:GPF 1 "memory_operand" ""))
48 (set (match_operand:GPF 2 "register_operand" "")
49 (match_operand:GPF 3 "memory_operand" ""))]
50 "aarch64_operands_ok_for_ldpstp (operands, true, <MODE>mode)"
51 [(parallel [(set (match_dup 0) (match_dup 1))
52 (set (match_dup 2) (match_dup 3))])]
53 {
54 aarch64_swap_ldrstr_operands (operands, true);
55 })
56
57 (define_peephole2
58 [(set (match_operand:GPF 0 "memory_operand" "")
59 (match_operand:GPF 1 "aarch64_reg_or_fp_zero" ""))
60 (set (match_operand:GPF 2 "memory_operand" "")
61 (match_operand:GPF 3 "aarch64_reg_or_fp_zero" ""))]
62 "aarch64_operands_ok_for_ldpstp (operands, false, <MODE>mode)"
63 [(parallel [(set (match_dup 0) (match_dup 1))
64 (set (match_dup 2) (match_dup 3))])]
65 {
66 aarch64_swap_ldrstr_operands (operands, false);
67 })
68
69 (define_peephole2
70 [(set (match_operand:DREG 0 "register_operand" "")
71 (match_operand:DREG 1 "memory_operand" ""))
72 (set (match_operand:DREG2 2 "register_operand" "")
73 (match_operand:DREG2 3 "memory_operand" ""))]
74 "aarch64_operands_ok_for_ldpstp (operands, true, <DREG:MODE>mode)"
75 [(parallel [(set (match_dup 0) (match_dup 1))
76 (set (match_dup 2) (match_dup 3))])]
77 {
78 aarch64_swap_ldrstr_operands (operands, true);
79 })
80
81 (define_peephole2
82 [(set (match_operand:DREG 0 "memory_operand" "")
83 (match_operand:DREG 1 "register_operand" ""))
84 (set (match_operand:DREG2 2 "memory_operand" "")
85 (match_operand:DREG2 3 "register_operand" ""))]
86 "TARGET_SIMD
87 && aarch64_operands_ok_for_ldpstp (operands, false, <DREG:MODE>mode)"
88 [(parallel [(set (match_dup 0) (match_dup 1))
89 (set (match_dup 2) (match_dup 3))])]
90 {
91 aarch64_swap_ldrstr_operands (operands, false);
92 })
93
94 (define_peephole2
95 [(set (match_operand:VQ 0 "register_operand" "")
96 (match_operand:VQ 1 "memory_operand" ""))
97 (set (match_operand:VQ2 2 "register_operand" "")
98 (match_operand:VQ2 3 "memory_operand" ""))]
99 "TARGET_SIMD
100 && aarch64_operands_ok_for_ldpstp (operands, true, <VQ:MODE>mode)
101 && (aarch64_tune_params.extra_tuning_flags
102 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) == 0"
103 [(parallel [(set (match_dup 0) (match_dup 1))
104 (set (match_dup 2) (match_dup 3))])]
105 {
106 aarch64_swap_ldrstr_operands (operands, true);
107 })
108
109 (define_peephole2
110 [(set (match_operand:VQ 0 "memory_operand" "")
111 (match_operand:VQ 1 "register_operand" ""))
112 (set (match_operand:VQ2 2 "memory_operand" "")
113 (match_operand:VQ2 3 "register_operand" ""))]
114 "TARGET_SIMD
115 && aarch64_operands_ok_for_ldpstp (operands, false, <VQ:MODE>mode)
116 && (aarch64_tune_params.extra_tuning_flags
117 & AARCH64_EXTRA_TUNE_NO_LDP_STP_QREGS) == 0"
118 [(parallel [(set (match_dup 0) (match_dup 1))
119 (set (match_dup 2) (match_dup 3))])]
120 {
121 aarch64_swap_ldrstr_operands (operands, false);
122 })
123
124
125 ;; Handle sign/zero extended consecutive load/store.
126
127 (define_peephole2
128 [(set (match_operand:DI 0 "register_operand" "")
129 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))
130 (set (match_operand:DI 2 "register_operand" "")
131 (sign_extend:DI (match_operand:SI 3 "memory_operand" "")))]
132 "aarch64_operands_ok_for_ldpstp (operands, true, SImode)"
133 [(parallel [(set (match_dup 0) (sign_extend:DI (match_dup 1)))
134 (set (match_dup 2) (sign_extend:DI (match_dup 3)))])]
135 {
136 aarch64_swap_ldrstr_operands (operands, true);
137 })
138
139 (define_peephole2
140 [(set (match_operand:DI 0 "register_operand" "")
141 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))
142 (set (match_operand:DI 2 "register_operand" "")
143 (zero_extend:DI (match_operand:SI 3 "memory_operand" "")))]
144 "aarch64_operands_ok_for_ldpstp (operands, true, SImode)"
145 [(parallel [(set (match_dup 0) (zero_extend:DI (match_dup 1)))
146 (set (match_dup 2) (zero_extend:DI (match_dup 3)))])]
147 {
148 aarch64_swap_ldrstr_operands (operands, true);
149 })
150
151 ;; Handle storing of a floating point zero with integer data.
152 ;; This handles cases like:
153 ;; struct pair { int a; float b; }
154 ;;
155 ;; p->a = 1;
156 ;; p->b = 0.0;
157 ;;
158 ;; We can match modes that won't work for a stp instruction
159 ;; as aarch64_operands_ok_for_ldpstp checks that the modes are
160 ;; compatible.
161 (define_peephole2
162 [(set (match_operand:DSX 0 "memory_operand" "")
163 (match_operand:DSX 1 "aarch64_reg_zero_or_fp_zero" ""))
164 (set (match_operand:<FCVT_TARGET> 2 "memory_operand" "")
165 (match_operand:<FCVT_TARGET> 3 "aarch64_reg_zero_or_fp_zero" ""))]
166 "aarch64_operands_ok_for_ldpstp (operands, false, <V_INT_EQUIV>mode)"
167 [(parallel [(set (match_dup 0) (match_dup 1))
168 (set (match_dup 2) (match_dup 3))])]
169 {
170 aarch64_swap_ldrstr_operands (operands, false);
171 })
172
173 ;; Handle consecutive load/store whose offset is out of the range
174 ;; supported by ldp/ldpsw/stp. We firstly adjust offset in a scratch
175 ;; register, then merge them into ldp/ldpsw/stp by using the adjusted
176 ;; offset.
177
178 (define_peephole2
179 [(match_scratch:DI 8 "r")
180 (set (match_operand:GPI 0 "register_operand" "")
181 (match_operand:GPI 1 "memory_operand" ""))
182 (set (match_operand:GPI 2 "register_operand" "")
183 (match_operand:GPI 3 "memory_operand" ""))
184 (set (match_operand:GPI 4 "register_operand" "")
185 (match_operand:GPI 5 "memory_operand" ""))
186 (set (match_operand:GPI 6 "register_operand" "")
187 (match_operand:GPI 7 "memory_operand" ""))
188 (match_dup 8)]
189 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, <MODE>mode)"
190 [(const_int 0)]
191 {
192 if (aarch64_gen_adjusted_ldpstp (operands, true, <MODE>mode, UNKNOWN))
193 DONE;
194 else
195 FAIL;
196 })
197
198 (define_peephole2
199 [(match_scratch:DI 8 "r")
200 (set (match_operand:GPF 0 "register_operand" "")
201 (match_operand:GPF 1 "memory_operand" ""))
202 (set (match_operand:GPF 2 "register_operand" "")
203 (match_operand:GPF 3 "memory_operand" ""))
204 (set (match_operand:GPF 4 "register_operand" "")
205 (match_operand:GPF 5 "memory_operand" ""))
206 (set (match_operand:GPF 6 "register_operand" "")
207 (match_operand:GPF 7 "memory_operand" ""))
208 (match_dup 8)]
209 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, <MODE>mode)"
210 [(const_int 0)]
211 {
212 if (aarch64_gen_adjusted_ldpstp (operands, true, <MODE>mode, UNKNOWN))
213 DONE;
214 else
215 FAIL;
216 })
217
218 (define_peephole2
219 [(match_scratch:DI 8 "r")
220 (set (match_operand:DI 0 "register_operand" "")
221 (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))
222 (set (match_operand:DI 2 "register_operand" "")
223 (sign_extend:DI (match_operand:SI 3 "memory_operand" "")))
224 (set (match_operand:DI 4 "register_operand" "")
225 (sign_extend:DI (match_operand:SI 5 "memory_operand" "")))
226 (set (match_operand:DI 6 "register_operand" "")
227 (sign_extend:DI (match_operand:SI 7 "memory_operand" "")))
228 (match_dup 8)]
229 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, SImode)"
230 [(const_int 0)]
231 {
232 if (aarch64_gen_adjusted_ldpstp (operands, true, SImode, SIGN_EXTEND))
233 DONE;
234 else
235 FAIL;
236 })
237
238 (define_peephole2
239 [(match_scratch:DI 8 "r")
240 (set (match_operand:DI 0 "register_operand" "")
241 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))
242 (set (match_operand:DI 2 "register_operand" "")
243 (zero_extend:DI (match_operand:SI 3 "memory_operand" "")))
244 (set (match_operand:DI 4 "register_operand" "")
245 (zero_extend:DI (match_operand:SI 5 "memory_operand" "")))
246 (set (match_operand:DI 6 "register_operand" "")
247 (zero_extend:DI (match_operand:SI 7 "memory_operand" "")))
248 (match_dup 8)]
249 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, SImode)"
250 [(const_int 0)]
251 {
252 if (aarch64_gen_adjusted_ldpstp (operands, true, SImode, ZERO_EXTEND))
253 DONE;
254 else
255 FAIL;
256 })
257
258 (define_peephole2
259 [(match_scratch:DI 8 "r")
260 (set (match_operand:GPI 0 "memory_operand" "")
261 (match_operand:GPI 1 "aarch64_reg_or_zero" ""))
262 (set (match_operand:GPI 2 "memory_operand" "")
263 (match_operand:GPI 3 "aarch64_reg_or_zero" ""))
264 (set (match_operand:GPI 4 "memory_operand" "")
265 (match_operand:GPI 5 "aarch64_reg_or_zero" ""))
266 (set (match_operand:GPI 6 "memory_operand" "")
267 (match_operand:GPI 7 "aarch64_reg_or_zero" ""))
268 (match_dup 8)]
269 "aarch64_operands_adjust_ok_for_ldpstp (operands, false, <MODE>mode)"
270 [(const_int 0)]
271 {
272 if (aarch64_gen_adjusted_ldpstp (operands, false, <MODE>mode, UNKNOWN))
273 DONE;
274 else
275 FAIL;
276 })
277
278 (define_peephole2
279 [(match_scratch:DI 8 "r")
280 (set (match_operand:GPF 0 "memory_operand" "")
281 (match_operand:GPF 1 "aarch64_reg_or_fp_zero" ""))
282 (set (match_operand:GPF 2 "memory_operand" "")
283 (match_operand:GPF 3 "aarch64_reg_or_fp_zero" ""))
284 (set (match_operand:GPF 4 "memory_operand" "")
285 (match_operand:GPF 5 "aarch64_reg_or_fp_zero" ""))
286 (set (match_operand:GPF 6 "memory_operand" "")
287 (match_operand:GPF 7 "aarch64_reg_or_fp_zero" ""))
288 (match_dup 8)]
289 "aarch64_operands_adjust_ok_for_ldpstp (operands, false, <MODE>mode)"
290 [(const_int 0)]
291 {
292 if (aarch64_gen_adjusted_ldpstp (operands, false, <MODE>mode, UNKNOWN))
293 DONE;
294 else
295 FAIL;
296 })
297
298 (define_peephole2
299 [(match_scratch:DI 8 "r")
300 (set (match_operand:VP_2E 0 "memory_operand" "")
301 (match_operand:VP_2E 1 "aarch64_reg_or_zero" ""))
302 (set (match_operand:VP_2E 2 "memory_operand" "")
303 (match_operand:VP_2E 3 "aarch64_reg_or_zero" ""))
304 (set (match_operand:VP_2E 4 "memory_operand" "")
305 (match_operand:VP_2E 5 "aarch64_reg_or_zero" ""))
306 (set (match_operand:VP_2E 6 "memory_operand" "")
307 (match_operand:VP_2E 7 "aarch64_reg_or_zero" ""))
308 (match_dup 8)]
309 "TARGET_SIMD
310 && aarch64_operands_adjust_ok_for_ldpstp (operands, false, <MODE>mode)"
311 [(const_int 0)]
312 {
313 if (aarch64_gen_adjusted_ldpstp (operands, false, <MODE>mode, UNKNOWN))
314 DONE;
315 else
316 FAIL;
317 })
318
319 (define_peephole2
320 [(match_scratch:DI 8 "r")
321 (set (match_operand:VP_2E 0 "register_operand" "")
322 (match_operand:VP_2E 1 "memory_operand" ""))
323 (set (match_operand:VP_2E 2 "register_operand" "")
324 (match_operand:VP_2E 3 "memory_operand" ""))
325 (set (match_operand:VP_2E 4 "register_operand" "")
326 (match_operand:VP_2E 5 "memory_operand" ""))
327 (set (match_operand:VP_2E 6 "register_operand" "")
328 (match_operand:VP_2E 7 "memory_operand" ""))
329 (match_dup 8)]
330 "TARGET_SIMD
331 && aarch64_operands_adjust_ok_for_ldpstp (operands, true, <MODE>mode)"
332 [(const_int 0)]
333 {
334 if (aarch64_gen_adjusted_ldpstp (operands, true, <MODE>mode, UNKNOWN))
335 DONE;
336 else
337 FAIL;
338 })