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