1 ;; AArch64 ldp/stp peephole optimizations.
2 ;; Copyright (C) 2014-2019 Free Software Foundation, Inc.
3 ;; Contributed by ARM Ltd.
5 ;; This file is part of GCC.
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)
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.
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/>.
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))])]
30 aarch64_swap_ldrstr_operands (operands, true);
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))])]
42 aarch64_swap_ldrstr_operands (operands, false);
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))])]
54 aarch64_swap_ldrstr_operands (operands, true);
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))])]
66 aarch64_swap_ldrstr_operands (operands, false);
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))])]
78 aarch64_swap_ldrstr_operands (operands, true);
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" ""))]
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))])]
91 aarch64_swap_ldrstr_operands (operands, false);
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" ""))]
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))])]
106 aarch64_swap_ldrstr_operands (operands, true);
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" ""))]
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))])]
121 aarch64_swap_ldrstr_operands (operands, false);
125 ;; Handle sign/zero extended consecutive load/store.
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)))])]
136 aarch64_swap_ldrstr_operands (operands, true);
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)))])]
148 aarch64_swap_ldrstr_operands (operands, true);
151 ;; Handle storing of a floating point zero with integer data.
152 ;; This handles cases like:
153 ;; struct pair { int a; float b; }
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
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))])]
170 aarch64_swap_ldrstr_operands (operands, false);
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
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" ""))
189 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, <MODE>mode)"
192 if (aarch64_gen_adjusted_ldpstp (operands, true, <MODE>mode, UNKNOWN))
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" ""))
209 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, <MODE>mode)"
212 if (aarch64_gen_adjusted_ldpstp (operands, true, <MODE>mode, UNKNOWN))
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" "")))
229 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, SImode)"
232 if (aarch64_gen_adjusted_ldpstp (operands, true, SImode, SIGN_EXTEND))
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" "")))
249 "aarch64_operands_adjust_ok_for_ldpstp (operands, true, SImode)"
252 if (aarch64_gen_adjusted_ldpstp (operands, true, SImode, ZERO_EXTEND))
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" ""))
269 "aarch64_operands_adjust_ok_for_ldpstp (operands, false, <MODE>mode)"
272 if (aarch64_gen_adjusted_ldpstp (operands, false, <MODE>mode, UNKNOWN))
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" ""))
289 "aarch64_operands_adjust_ok_for_ldpstp (operands, false, <MODE>mode)"
292 if (aarch64_gen_adjusted_ldpstp (operands, false, <MODE>mode, UNKNOWN))