1 /* Dependency checks for instruction scheduling, shared between ARM and
4 Copyright (C) 1991-2014 Free Software Foundation, Inc.
5 Contributed by ARM Ltd.
7 This file is part of GCC.
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.
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.
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/>. */
26 #include "coretypes.h"
31 #include "c-family/c-common.h"
34 /* In ARMv8-A there's a general expectation that AESE/AESMC
35 and AESD/AESIMC sequences of the form:
40 will issue both instructions in a single cycle on super-scalar
41 implementations. This function identifies such pairs. */
44 aarch_crypto_can_dual_issue (rtx_insn
*producer_insn
, rtx_insn
*consumer_insn
)
46 rtx producer_set
, consumer_set
;
47 rtx producer_src
, consumer_src
;
49 producer_set
= single_set (producer_insn
);
50 consumer_set
= single_set (consumer_insn
);
52 producer_src
= producer_set
? SET_SRC (producer_set
) : NULL
;
53 consumer_src
= consumer_set
? SET_SRC (consumer_set
) : NULL
;
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
)))
62 unsigned int regno
= REGNO (SET_DEST (producer_set
));
64 return REGNO (SET_DEST (consumer_set
)) == regno
65 && REGNO (XVECEXP (consumer_src
, 0, 0)) == regno
;
78 /* Return TRUE if X is either an arithmetic shift left, or
79 is a multiplication by a power of two. */
81 arm_rtx_shift_left_p (rtx x
)
83 enum rtx_code code
= GET_CODE (x
);
85 if (code
== MULT
&& CONST_INT_P (XEXP (x
, 1))
86 && exact_log2 (INTVAL (XEXP (x
, 1))) > 0)
95 static rtx_code shift_rtx_codes
[] =
96 { ASHIFT
, ROTATE
, ASHIFTRT
, LSHIFTRT
,
97 ROTATERT
, ZERO_EXTEND
, SIGN_EXTEND
};
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. */
107 arm_find_sub_rtx_with_search_term (rtx
*pattern
, void *data
)
109 search_term
*st
= (search_term
*) data
;
110 rtx_code pattern_code
;
113 gcc_assert (pattern
);
116 /* Poorly formed patterns can really ruin our day. */
117 if (*pattern
== NULL_RTX
)
120 pattern_code
= GET_CODE (*pattern
);
122 if (st
->find_any_shift
)
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
))
131 for (i
= 0; i
< ARRAY_SIZE (shift_rtx_codes
); i
++)
132 if (pattern_code
== shift_rtx_codes
[i
])
136 if (pattern_code
== st
->search_code
)
140 st
->search_result
= *pattern
;
145 /* Traverse PATTERN looking for a sub-rtx with RTX_CODE CODE. */
147 arm_find_sub_rtx_with_code (rtx pattern
, rtx_code code
, bool find_any_shift
)
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
);
158 return st
.search_result
;
163 /* Traverse PATTERN looking for any sub-rtx which looks like a shift. */
165 arm_find_shift_sub_rtx (rtx pattern
)
167 return arm_find_sub_rtx_with_code (pattern
, ASHIFT
, true);
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
178 Return nonzero if we found the SET RTX we expected. */
180 arm_get_set_operands (rtx producer
, rtx consumer
,
181 rtx
*set_source
, rtx
*set_destination
)
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);
186 if (set_producer
&& set_consumer
)
188 *set_source
= SET_DEST (set_producer
);
189 *set_destination
= SET_SRC (set_consumer
);
196 aarch_rev16_shright_mask_imm_p (rtx val
, machine_mode mode
)
198 return CONST_INT_P (val
)
200 == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff),
205 aarch_rev16_shleft_mask_imm_p (rtx val
, machine_mode mode
)
207 return CONST_INT_P (val
)
209 == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff00),
215 aarch_rev16_p_1 (rtx lhs
, rtx rhs
, machine_mode mode
)
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)))
232 rtx lhs_mask
= XEXP (lhs
, 1);
233 rtx rhs_mask
= XEXP (rhs
, 1);
235 return aarch_rev16_shright_mask_imm_p (rhs_mask
, mode
)
236 && aarch_rev16_shleft_mask_imm_p (lhs_mask
, mode
);
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. */
251 aarch_rev16_p (rtx x
)
253 rtx left_sub_rtx
, right_sub_rtx
;
256 if (GET_CODE (x
) != IOR
)
259 left_sub_rtx
= XEXP (x
, 0);
260 right_sub_rtx
= XEXP (x
, 1);
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
));
267 is_rev
= aarch_rev16_p_1 (right_sub_rtx
, left_sub_rtx
, GET_MODE (x
));
272 /* Return nonzero if the CONSUMER instruction (a load) does need
273 PRODUCER's value to calculate the address. */
275 arm_early_load_addr_dep (rtx producer
, rtx consumer
)
279 if (!arm_get_set_operands (producer
, consumer
, &value
, &addr
))
282 return reg_overlap_mentioned_p (value
, addr
);
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. */
289 arm_no_early_alu_shift_dep (rtx producer
, rtx consumer
)
294 if (!arm_get_set_operands (producer
, consumer
, &value
, &op
))
297 if ((early_op
= arm_find_shift_sub_rtx (op
)))
299 if (REG_P (early_op
))
302 return !reg_overlap_mentioned_p (value
, early_op
);
308 /* Return nonzero if the CONSUMER instruction (an ALU op) does not
309 have an early register shift value dependency on the result of
312 arm_no_early_alu_shift_value_dep (rtx producer
, rtx consumer
)
317 if (!arm_get_set_operands (producer
, consumer
, &value
, &op
))
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)))
328 /* Return nonzero if the CONSUMER (a mul or mac op) does not
329 have an early register mult dependency on the result of
332 arm_no_early_mul_dep (rtx producer
, rtx consumer
)
336 if (!arm_get_set_operands (producer
, consumer
, &value
, &op
))
339 if (GET_CODE (op
) == PLUS
|| GET_CODE (op
) == MINUS
)
341 if (GET_CODE (XEXP (op
, 0)) == MULT
)
342 return !reg_overlap_mentioned_p (value
, XEXP (op
, 0));
344 return !reg_overlap_mentioned_p (value
, XEXP (op
, 1));
350 /* Return nonzero if the CONSUMER instruction (a store) does not need
351 PRODUCER's value to calculate the address. */
354 arm_no_early_store_addr_dep (rtx producer
, rtx consumer
)
356 rtx value
= arm_find_sub_rtx_with_code (producer
, SET
, false);
357 rtx addr
= arm_find_sub_rtx_with_code (consumer
, SET
, false);
360 value
= SET_DEST (value
);
363 addr
= SET_DEST (addr
);
368 return !reg_overlap_mentioned_p (value
, addr
);
371 /* Return nonzero if the CONSUMER instruction (a store) does need
372 PRODUCER's value to calculate the address. */
375 arm_early_store_addr_dep (rtx producer
, rtx consumer
)
377 return !arm_no_early_store_addr_dep (producer
, consumer
);
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. */
385 arm_mac_accumulator_is_result (rtx producer
, rtx consumer
)
390 producer
= PATTERN (producer
);
391 consumer
= PATTERN (consumer
);
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
);
398 if (GET_CODE (producer
) != SET
)
401 result
= XEXP (producer
, 0);
403 if (GET_CODE (consumer
) != SET
)
406 /* Check that the consumer is of the form
407 (set (...) (plus (mult ...) (...)))
409 (set (...) (minus (...) (mult ...))). */
410 if (GET_CODE (XEXP (consumer
, 1)) == PLUS
)
412 if (GET_CODE (XEXP (XEXP (consumer
, 1), 0)) != MULT
)
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);
419 else if (GET_CODE (XEXP (consumer
, 1)) == MINUS
)
421 if (GET_CODE (XEXP (XEXP (consumer
, 1), 1)) != MULT
)
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);
431 return (reg_overlap_mentioned_p (result
, acc
)
432 && !reg_overlap_mentioned_p (result
, op0
)
433 && !reg_overlap_mentioned_p (result
, op1
));
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. */
440 arm_mac_accumulator_is_mul_result (rtx producer
, rtx consumer
)
442 rtx mul
= PATTERN (producer
);
443 rtx mac
= PATTERN (consumer
);
445 rtx mac_op0
, mac_op1
, mac_acc
;
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
);
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
))
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);
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
));