aarch-common.c: Include rtl-iter.h.
[gcc.git] / gcc / config / arm / aarch-common.c
1 /* Dependency checks for instruction scheduling, shared between ARM and
2 AARCH64.
3
4 Copyright (C) 1991-2014 Free Software Foundation, Inc.
5 Contributed by ARM Ltd.
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
11 by the Free Software Foundation; either version 3, or (at your
12 option) any later version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 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
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tm_p.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "c-family/c-common.h"
32 #include "rtl.h"
33 #include "rtl-iter.h"
34
35 /* In ARMv8-A there's a general expectation that AESE/AESMC
36 and AESD/AESIMC sequences of the form:
37
38 AESE Vn, _
39 AESMC Vn, Vn
40
41 will issue both instructions in a single cycle on super-scalar
42 implementations. This function identifies such pairs. */
43
44 int
45 aarch_crypto_can_dual_issue (rtx_insn *producer_insn, rtx_insn *consumer_insn)
46 {
47 rtx producer_set, consumer_set;
48 rtx producer_src, consumer_src;
49
50 producer_set = single_set (producer_insn);
51 consumer_set = single_set (consumer_insn);
52
53 producer_src = producer_set ? SET_SRC (producer_set) : NULL;
54 consumer_src = consumer_set ? SET_SRC (consumer_set) : NULL;
55
56 if (producer_src && consumer_src
57 && GET_CODE (producer_src) == UNSPEC && GET_CODE (consumer_src) == UNSPEC
58 && ((XINT (producer_src, 1) == UNSPEC_AESE
59 && XINT (consumer_src, 1) == UNSPEC_AESMC)
60 || (XINT (producer_src, 1) == UNSPEC_AESD
61 && XINT (consumer_src, 1) == UNSPEC_AESIMC)))
62 {
63 unsigned int regno = REGNO (SET_DEST (producer_set));
64
65 return REGNO (SET_DEST (consumer_set)) == regno
66 && REGNO (XVECEXP (consumer_src, 0, 0)) == regno;
67 }
68
69 return 0;
70 }
71
72 /* Return TRUE if X is either an arithmetic shift left, or
73 is a multiplication by a power of two. */
74 bool
75 arm_rtx_shift_left_p (rtx x)
76 {
77 enum rtx_code code = GET_CODE (x);
78
79 if (code == MULT && CONST_INT_P (XEXP (x, 1))
80 && exact_log2 (INTVAL (XEXP (x, 1))) > 0)
81 return true;
82
83 if (code == ASHIFT)
84 return true;
85
86 return false;
87 }
88
89 static rtx_code shift_rtx_codes[] =
90 { ASHIFT, ROTATE, ASHIFTRT, LSHIFTRT,
91 ROTATERT, ZERO_EXTEND, SIGN_EXTEND };
92
93 /* Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE.
94 If FIND_ANY_SHIFT then we are interested in anything which can
95 reasonably be described as a SHIFT RTX. */
96 static rtx
97 arm_find_sub_rtx_with_code (rtx pattern, rtx_code code, bool find_any_shift)
98 {
99 subrtx_var_iterator::array_type array;
100 FOR_EACH_SUBRTX_VAR (iter, array, pattern, NONCONST)
101 {
102 rtx x = *iter;
103 if (find_any_shift)
104 {
105 /* Left shifts might have been canonicalized to a MULT of some
106 power of two. Make sure we catch them. */
107 if (arm_rtx_shift_left_p (x))
108 return x;
109 else
110 for (unsigned int i = 0; i < ARRAY_SIZE (shift_rtx_codes); i++)
111 if (GET_CODE (x) == shift_rtx_codes[i])
112 return x;
113 }
114
115 if (GET_CODE (x) == code)
116 return x;
117 }
118 return NULL_RTX;
119 }
120
121 /* Traverse PATTERN looking for any sub-rtx which looks like a shift. */
122 static rtx
123 arm_find_shift_sub_rtx (rtx pattern)
124 {
125 return arm_find_sub_rtx_with_code (pattern, ASHIFT, true);
126 }
127
128 /* PRODUCER and CONSUMER are two potentially dependant RTX. PRODUCER
129 (possibly) contains a SET which will provide a result we can access
130 using the SET_DEST macro. We will place the RTX which would be
131 written by PRODUCER in SET_SOURCE.
132 Similarly, CONSUMER (possibly) contains a SET which has an operand
133 we can access using SET_SRC. We place this operand in
134 SET_DESTINATION.
135
136 Return nonzero if we found the SET RTX we expected. */
137 static int
138 arm_get_set_operands (rtx producer, rtx consumer,
139 rtx *set_source, rtx *set_destination)
140 {
141 rtx set_producer = arm_find_sub_rtx_with_code (PATTERN (producer),
142 SET, false);
143 rtx set_consumer = arm_find_sub_rtx_with_code (PATTERN (consumer),
144 SET, false);
145
146 if (set_producer && set_consumer)
147 {
148 *set_source = SET_DEST (set_producer);
149 *set_destination = SET_SRC (set_consumer);
150 return 1;
151 }
152 return 0;
153 }
154
155 bool
156 aarch_rev16_shright_mask_imm_p (rtx val, machine_mode mode)
157 {
158 return CONST_INT_P (val)
159 && INTVAL (val)
160 == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff),
161 mode);
162 }
163
164 bool
165 aarch_rev16_shleft_mask_imm_p (rtx val, machine_mode mode)
166 {
167 return CONST_INT_P (val)
168 && INTVAL (val)
169 == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff00),
170 mode);
171 }
172
173
174 static bool
175 aarch_rev16_p_1 (rtx lhs, rtx rhs, machine_mode mode)
176 {
177 if (GET_CODE (lhs) == AND
178 && GET_CODE (XEXP (lhs, 0)) == ASHIFT
179 && CONST_INT_P (XEXP (XEXP (lhs, 0), 1))
180 && INTVAL (XEXP (XEXP (lhs, 0), 1)) == 8
181 && REG_P (XEXP (XEXP (lhs, 0), 0))
182 && CONST_INT_P (XEXP (lhs, 1))
183 && GET_CODE (rhs) == AND
184 && GET_CODE (XEXP (rhs, 0)) == LSHIFTRT
185 && REG_P (XEXP (XEXP (rhs, 0), 0))
186 && CONST_INT_P (XEXP (XEXP (rhs, 0), 1))
187 && INTVAL (XEXP (XEXP (rhs, 0), 1)) == 8
188 && CONST_INT_P (XEXP (rhs, 1))
189 && REGNO (XEXP (XEXP (rhs, 0), 0)) == REGNO (XEXP (XEXP (lhs, 0), 0)))
190
191 {
192 rtx lhs_mask = XEXP (lhs, 1);
193 rtx rhs_mask = XEXP (rhs, 1);
194
195 return aarch_rev16_shright_mask_imm_p (rhs_mask, mode)
196 && aarch_rev16_shleft_mask_imm_p (lhs_mask, mode);
197 }
198
199 return false;
200 }
201
202 /* Recognise a sequence of bitwise operations corresponding to a rev16 operation.
203 These will be of the form:
204 ((x >> 8) & 0x00ff00ff)
205 | ((x << 8) & 0xff00ff00)
206 for SImode and with similar but wider bitmasks for DImode.
207 The two sub-expressions of the IOR can appear on either side so check both
208 permutations with the help of aarch_rev16_p_1 above. */
209
210 bool
211 aarch_rev16_p (rtx x)
212 {
213 rtx left_sub_rtx, right_sub_rtx;
214 bool is_rev = false;
215
216 if (GET_CODE (x) != IOR)
217 return false;
218
219 left_sub_rtx = XEXP (x, 0);
220 right_sub_rtx = XEXP (x, 1);
221
222 /* There are no canonicalisation rules for the position of the two shifts
223 involved in a rev, so try both permutations. */
224 is_rev = aarch_rev16_p_1 (left_sub_rtx, right_sub_rtx, GET_MODE (x));
225
226 if (!is_rev)
227 is_rev = aarch_rev16_p_1 (right_sub_rtx, left_sub_rtx, GET_MODE (x));
228
229 return is_rev;
230 }
231
232 /* Return nonzero if the CONSUMER instruction (a load) does need
233 PRODUCER's value to calculate the address. */
234 int
235 arm_early_load_addr_dep (rtx producer, rtx consumer)
236 {
237 rtx value, addr;
238
239 if (!arm_get_set_operands (producer, consumer, &value, &addr))
240 return 0;
241
242 return reg_overlap_mentioned_p (value, addr);
243 }
244
245 /* Return nonzero if the CONSUMER instruction (an ALU op) does not
246 have an early register shift value or amount dependency on the
247 result of PRODUCER. */
248 int
249 arm_no_early_alu_shift_dep (rtx producer, rtx consumer)
250 {
251 rtx value, op;
252 rtx early_op;
253
254 if (!arm_get_set_operands (producer, consumer, &value, &op))
255 return 0;
256
257 if ((early_op = arm_find_shift_sub_rtx (op)))
258 {
259 if (REG_P (early_op))
260 early_op = op;
261
262 return !reg_overlap_mentioned_p (value, early_op);
263 }
264
265 return 0;
266 }
267
268 /* Return nonzero if the CONSUMER instruction (an ALU op) does not
269 have an early register shift value dependency on the result of
270 PRODUCER. */
271 int
272 arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer)
273 {
274 rtx value, op;
275 rtx early_op;
276
277 if (!arm_get_set_operands (producer, consumer, &value, &op))
278 return 0;
279
280 if ((early_op = arm_find_shift_sub_rtx (op)))
281 /* We want to check the value being shifted. */
282 if (!reg_overlap_mentioned_p (value, XEXP (early_op, 0)))
283 return 1;
284
285 return 0;
286 }
287
288 /* Return nonzero if the CONSUMER (a mul or mac op) does not
289 have an early register mult dependency on the result of
290 PRODUCER. */
291 int
292 arm_no_early_mul_dep (rtx producer, rtx consumer)
293 {
294 rtx value, op;
295
296 if (!arm_get_set_operands (producer, consumer, &value, &op))
297 return 0;
298
299 if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
300 {
301 if (GET_CODE (XEXP (op, 0)) == MULT)
302 return !reg_overlap_mentioned_p (value, XEXP (op, 0));
303 else
304 return !reg_overlap_mentioned_p (value, XEXP (op, 1));
305 }
306
307 return 0;
308 }
309
310 /* Return nonzero if the CONSUMER instruction (a store) does not need
311 PRODUCER's value to calculate the address. */
312
313 int
314 arm_no_early_store_addr_dep (rtx producer, rtx consumer)
315 {
316 rtx value = arm_find_sub_rtx_with_code (PATTERN (producer), SET, false);
317 rtx addr = arm_find_sub_rtx_with_code (PATTERN (consumer), SET, false);
318
319 if (value)
320 value = SET_DEST (value);
321
322 if (addr)
323 addr = SET_DEST (addr);
324
325 if (!value || !addr)
326 return 0;
327
328 return !reg_overlap_mentioned_p (value, addr);
329 }
330
331 /* Return nonzero if the CONSUMER instruction (a store) does need
332 PRODUCER's value to calculate the address. */
333
334 int
335 arm_early_store_addr_dep (rtx producer, rtx consumer)
336 {
337 return !arm_no_early_store_addr_dep (producer, consumer);
338 }
339
340 /* Return non-zero iff the consumer (a multiply-accumulate or a
341 multiple-subtract instruction) has an accumulator dependency on the
342 result of the producer and no other dependency on that result. It
343 does not check if the producer is multiply-accumulate instruction. */
344 int
345 arm_mac_accumulator_is_result (rtx producer, rtx consumer)
346 {
347 rtx result;
348 rtx op0, op1, acc;
349
350 producer = PATTERN (producer);
351 consumer = PATTERN (consumer);
352
353 if (GET_CODE (producer) == COND_EXEC)
354 producer = COND_EXEC_CODE (producer);
355 if (GET_CODE (consumer) == COND_EXEC)
356 consumer = COND_EXEC_CODE (consumer);
357
358 if (GET_CODE (producer) != SET)
359 return 0;
360
361 result = XEXP (producer, 0);
362
363 if (GET_CODE (consumer) != SET)
364 return 0;
365
366 /* Check that the consumer is of the form
367 (set (...) (plus (mult ...) (...)))
368 or
369 (set (...) (minus (...) (mult ...))). */
370 if (GET_CODE (XEXP (consumer, 1)) == PLUS)
371 {
372 if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT)
373 return 0;
374
375 op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0);
376 op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1);
377 acc = XEXP (XEXP (consumer, 1), 1);
378 }
379 else if (GET_CODE (XEXP (consumer, 1)) == MINUS)
380 {
381 if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT)
382 return 0;
383
384 op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0);
385 op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1);
386 acc = XEXP (XEXP (consumer, 1), 0);
387 }
388 else
389 return 0;
390
391 return (reg_overlap_mentioned_p (result, acc)
392 && !reg_overlap_mentioned_p (result, op0)
393 && !reg_overlap_mentioned_p (result, op1));
394 }
395
396 /* Return non-zero if the consumer (a multiply-accumulate instruction)
397 has an accumulator dependency on the result of the producer (a
398 multiplication instruction) and no other dependency on that result. */
399 int
400 arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer)
401 {
402 rtx mul = PATTERN (producer);
403 rtx mac = PATTERN (consumer);
404 rtx mul_result;
405 rtx mac_op0, mac_op1, mac_acc;
406
407 if (GET_CODE (mul) == COND_EXEC)
408 mul = COND_EXEC_CODE (mul);
409 if (GET_CODE (mac) == COND_EXEC)
410 mac = COND_EXEC_CODE (mac);
411
412 /* Check that mul is of the form (set (...) (mult ...))
413 and mla is of the form (set (...) (plus (mult ...) (...))). */
414 if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT)
415 || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS
416 || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT))
417 return 0;
418
419 mul_result = XEXP (mul, 0);
420 mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0);
421 mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1);
422 mac_acc = XEXP (XEXP (mac, 1), 1);
423
424 return (reg_overlap_mentioned_p (mul_result, mac_acc)
425 && !reg_overlap_mentioned_p (mul_result, mac_op0)
426 && !reg_overlap_mentioned_p (mul_result, mac_op1));
427 }