1 /* IR-agnostic target query functions relating to optabs
2 Copyright (C) 1987-2017 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
23 #include "coretypes.h"
25 #include "insn-codes.h"
26 #include "optabs-query.h"
27 #include "optabs-libfuncs.h"
28 #include "insn-config.h"
32 struct target_optabs default_target_optabs
;
33 struct target_optabs
*this_fn_optabs
= &default_target_optabs
;
35 struct target_optabs
*this_target_optabs
= &default_target_optabs
;
38 /* Return the insn used to perform conversion OP from mode FROM_MODE
39 to mode TO_MODE; return CODE_FOR_nothing if the target does not have
40 such an insn, or if it is unsuitable for optimization type OPT_TYPE. */
43 convert_optab_handler (convert_optab optab
, machine_mode to_mode
,
44 machine_mode from_mode
, optimization_type opt_type
)
46 insn_code icode
= convert_optab_handler (optab
, to_mode
, from_mode
);
47 if (icode
== CODE_FOR_nothing
48 || !targetm
.optab_supported_p (optab
, to_mode
, from_mode
, opt_type
))
49 return CODE_FOR_nothing
;
53 /* Return the insn used to implement mode MODE of OP; return
54 CODE_FOR_nothing if the target does not have such an insn,
55 or if it is unsuitable for optimization type OPT_TYPE. */
58 direct_optab_handler (convert_optab optab
, machine_mode mode
,
59 optimization_type opt_type
)
61 insn_code icode
= direct_optab_handler (optab
, mode
);
62 if (icode
== CODE_FOR_nothing
63 || !targetm
.optab_supported_p (optab
, mode
, mode
, opt_type
))
64 return CODE_FOR_nothing
;
68 /* Enumerates the possible types of structure operand to an
70 enum extraction_type
{ ET_unaligned_mem
, ET_reg
};
72 /* Check whether insv, extv or extzv pattern ICODE can be used for an
73 insertion or extraction of type TYPE on a structure of mode MODE.
74 Return true if so and fill in *INSN accordingly. STRUCT_OP is the
75 operand number of the structure (the first sign_extract or zero_extract
76 operand) and FIELD_OP is the operand number of the field (the other
77 side of the set from the sign_extract or zero_extract). */
80 get_traditional_extraction_insn (extraction_insn
*insn
,
81 enum extraction_type type
,
84 int struct_op
, int field_op
)
86 const struct insn_data_d
*data
= &insn_data
[icode
];
88 machine_mode struct_mode
= data
->operand
[struct_op
].mode
;
89 if (struct_mode
== VOIDmode
)
90 struct_mode
= word_mode
;
91 if (mode
!= struct_mode
)
94 machine_mode field_mode
= data
->operand
[field_op
].mode
;
95 if (field_mode
== VOIDmode
)
96 field_mode
= word_mode
;
98 machine_mode pos_mode
= data
->operand
[struct_op
+ 2].mode
;
99 if (pos_mode
== VOIDmode
)
100 pos_mode
= word_mode
;
103 insn
->field_mode
= as_a
<scalar_int_mode
> (field_mode
);
104 if (type
== ET_unaligned_mem
)
105 insn
->struct_mode
= byte_mode
;
106 else if (struct_mode
== BLKmode
)
107 insn
->struct_mode
= opt_scalar_int_mode ();
109 insn
->struct_mode
= as_a
<scalar_int_mode
> (struct_mode
);
110 insn
->pos_mode
= as_a
<scalar_int_mode
> (pos_mode
);
114 /* Return true if an optab exists to perform an insertion or extraction
115 of type TYPE in mode MODE. Describe the instruction in *INSN if so.
117 REG_OPTAB is the optab to use for register structures and
118 MISALIGN_OPTAB is the optab to use for misaligned memory structures.
119 POS_OP is the operand number of the bit position. */
122 get_optab_extraction_insn (struct extraction_insn
*insn
,
123 enum extraction_type type
,
124 machine_mode mode
, direct_optab reg_optab
,
125 direct_optab misalign_optab
, int pos_op
)
127 direct_optab optab
= (type
== ET_unaligned_mem
? misalign_optab
: reg_optab
);
128 enum insn_code icode
= direct_optab_handler (optab
, mode
);
129 if (icode
== CODE_FOR_nothing
)
132 const struct insn_data_d
*data
= &insn_data
[icode
];
134 machine_mode pos_mode
= data
->operand
[pos_op
].mode
;
135 if (pos_mode
== VOIDmode
)
136 pos_mode
= word_mode
;
139 insn
->field_mode
= as_a
<scalar_int_mode
> (mode
);
140 if (type
== ET_unaligned_mem
)
141 insn
->struct_mode
= opt_scalar_int_mode ();
143 insn
->struct_mode
= insn
->field_mode
;
144 insn
->pos_mode
= as_a
<scalar_int_mode
> (pos_mode
);
148 /* Return true if an instruction exists to perform an insertion or
149 extraction (PATTERN says which) of type TYPE in mode MODE.
150 Describe the instruction in *INSN if so. */
153 get_extraction_insn (extraction_insn
*insn
,
154 enum extraction_pattern pattern
,
155 enum extraction_type type
,
161 if (targetm
.have_insv ()
162 && get_traditional_extraction_insn (insn
, type
, mode
,
163 targetm
.code_for_insv
, 0, 3))
165 return get_optab_extraction_insn (insn
, type
, mode
, insv_optab
,
166 insvmisalign_optab
, 2);
169 if (targetm
.have_extv ()
170 && get_traditional_extraction_insn (insn
, type
, mode
,
171 targetm
.code_for_extv
, 1, 0))
173 return get_optab_extraction_insn (insn
, type
, mode
, extv_optab
,
174 extvmisalign_optab
, 3);
177 if (targetm
.have_extzv ()
178 && get_traditional_extraction_insn (insn
, type
, mode
,
179 targetm
.code_for_extzv
, 1, 0))
181 return get_optab_extraction_insn (insn
, type
, mode
, extzv_optab
,
182 extzvmisalign_optab
, 3);
189 /* Return true if an instruction exists to access a field of mode
190 FIELDMODE in a structure that has STRUCT_BITS significant bits.
191 Describe the "best" such instruction in *INSN if so. PATTERN and
192 TYPE describe the type of insertion or extraction we want to perform.
194 For an insertion, the number of significant structure bits includes
195 all bits of the target. For an extraction, it need only include the
196 most significant bit of the field. Larger widths are acceptable
200 get_best_extraction_insn (extraction_insn
*insn
,
201 enum extraction_pattern pattern
,
202 enum extraction_type type
,
203 unsigned HOST_WIDE_INT struct_bits
,
204 machine_mode field_mode
)
206 opt_scalar_int_mode mode_iter
;
207 FOR_EACH_MODE_FROM (mode_iter
, smallest_int_mode_for_size (struct_bits
))
209 scalar_int_mode mode
= mode_iter
.require ();
210 if (get_extraction_insn (insn
, pattern
, type
, mode
))
212 FOR_EACH_MODE_FROM (mode_iter
, mode
)
214 mode
= mode_iter
.require ();
215 if (GET_MODE_SIZE (mode
) > GET_MODE_SIZE (field_mode
)
216 || TRULY_NOOP_TRUNCATION_MODES_P (insn
->field_mode
,
219 get_extraction_insn (insn
, pattern
, type
, mode
);
227 /* Return true if an instruction exists to access a field of mode
228 FIELDMODE in a register structure that has STRUCT_BITS significant bits.
229 Describe the "best" such instruction in *INSN if so. PATTERN describes
230 the type of insertion or extraction we want to perform.
232 For an insertion, the number of significant structure bits includes
233 all bits of the target. For an extraction, it need only include the
234 most significant bit of the field. Larger widths are acceptable
238 get_best_reg_extraction_insn (extraction_insn
*insn
,
239 enum extraction_pattern pattern
,
240 unsigned HOST_WIDE_INT struct_bits
,
241 machine_mode field_mode
)
243 return get_best_extraction_insn (insn
, pattern
, ET_reg
, struct_bits
,
247 /* Return true if an instruction exists to access a field of BITSIZE
248 bits starting BITNUM bits into a memory structure. Describe the
249 "best" such instruction in *INSN if so. PATTERN describes the type
250 of insertion or extraction we want to perform and FIELDMODE is the
251 natural mode of the extracted field.
253 The instructions considered here only access bytes that overlap
254 the bitfield; they do not touch any surrounding bytes. */
257 get_best_mem_extraction_insn (extraction_insn
*insn
,
258 enum extraction_pattern pattern
,
259 HOST_WIDE_INT bitsize
, HOST_WIDE_INT bitnum
,
260 machine_mode field_mode
)
262 unsigned HOST_WIDE_INT struct_bits
= (bitnum
% BITS_PER_UNIT
264 + BITS_PER_UNIT
- 1);
265 struct_bits
-= struct_bits
% BITS_PER_UNIT
;
266 return get_best_extraction_insn (insn
, pattern
, ET_unaligned_mem
,
267 struct_bits
, field_mode
);
270 /* Return the insn code used to extend FROM_MODE to TO_MODE.
271 UNSIGNEDP specifies zero-extension instead of sign-extension. If
272 no such operation exists, CODE_FOR_nothing will be returned. */
275 can_extend_p (machine_mode to_mode
, machine_mode from_mode
,
278 if (unsignedp
< 0 && targetm
.have_ptr_extend ())
279 return targetm
.code_for_ptr_extend
;
281 convert_optab tab
= unsignedp
? zext_optab
: sext_optab
;
282 return convert_optab_handler (tab
, to_mode
, from_mode
);
285 /* Return the insn code to convert fixed-point mode FIXMODE to floating-point
286 mode FLTMODE, or CODE_FOR_nothing if no such instruction exists.
287 UNSIGNEDP specifies whether FIXMODE is unsigned. */
290 can_float_p (machine_mode fltmode
, machine_mode fixmode
,
293 convert_optab tab
= unsignedp
? ufloat_optab
: sfloat_optab
;
294 return convert_optab_handler (tab
, fltmode
, fixmode
);
297 /* Return the insn code to convert floating-point mode FLTMODE to fixed-point
298 mode FIXMODE, or CODE_FOR_nothing if no such instruction exists.
299 UNSIGNEDP specifies whether FIXMODE is unsigned.
301 On a successful return, set *TRUNCP_PTR to true if it is necessary to
302 output an explicit FTRUNC before the instruction. */
305 can_fix_p (machine_mode fixmode
, machine_mode fltmode
,
306 int unsignedp
, bool *truncp_ptr
)
309 enum insn_code icode
;
311 tab
= unsignedp
? ufixtrunc_optab
: sfixtrunc_optab
;
312 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
313 if (icode
!= CODE_FOR_nothing
)
319 /* FIXME: This requires a port to define both FIX and FTRUNC pattern
320 for this to work. We need to rework the fix* and ftrunc* patterns
321 and documentation. */
322 tab
= unsignedp
? ufix_optab
: sfix_optab
;
323 icode
= convert_optab_handler (tab
, fixmode
, fltmode
);
324 if (icode
!= CODE_FOR_nothing
325 && optab_handler (ftrunc_optab
, fltmode
) != CODE_FOR_nothing
)
331 return CODE_FOR_nothing
;
334 /* Return nonzero if a conditional move of mode MODE is supported.
336 This function is for combine so it can tell whether an insn that looks
337 like a conditional move is actually supported by the hardware. If we
338 guess wrong we lose a bit on optimization, but that's it. */
339 /* ??? sparc64 supports conditionally moving integers values based on fp
340 comparisons, and vice versa. How do we handle them? */
343 can_conditionally_move_p (machine_mode mode
)
345 return direct_optab_handler (movcc_optab
, mode
) != CODE_FOR_nothing
;
348 /* Return true if VEC_PERM_EXPR of arbitrary input vectors can be
349 expanded using SIMD extensions of the CPU. SEL may be NULL, which
350 stands for an unknown constant. Note that additional permutations
351 representing whole-vector shifts may also be handled via the vec_shr
352 optab, but only where the second input vector is entirely constant
353 zeroes; this case is not dealt with here. */
356 can_vec_perm_p (machine_mode mode
, bool variable
, vec_perm_indices
*sel
)
360 /* If the target doesn't implement a vector mode for the vector type,
361 then no operations are supported. */
362 if (!VECTOR_MODE_P (mode
))
367 if (direct_optab_handler (vec_perm_const_optab
, mode
) != CODE_FOR_nothing
369 || targetm
.vectorize
.vec_perm_const_ok
== NULL
370 || targetm
.vectorize
.vec_perm_const_ok (mode
, *sel
)))
374 if (direct_optab_handler (vec_perm_optab
, mode
) != CODE_FOR_nothing
)
377 /* We allow fallback to a QI vector mode, and adjust the mask. */
378 if (GET_MODE_INNER (mode
) == QImode
379 || !mode_for_vector (QImode
, GET_MODE_SIZE (mode
)).exists (&qimode
)
380 || !VECTOR_MODE_P (qimode
))
383 /* ??? For completeness, we ought to check the QImode version of
384 vec_perm_const_optab. But all users of this implicit lowering
385 feature implement the variable vec_perm_optab. */
386 if (direct_optab_handler (vec_perm_optab
, qimode
) == CODE_FOR_nothing
)
389 /* In order to support the lowering of variable permutations,
390 we need to support shifts and adds. */
393 if (GET_MODE_UNIT_SIZE (mode
) > 2
394 && optab_handler (ashl_optab
, mode
) == CODE_FOR_nothing
395 && optab_handler (vashl_optab
, mode
) == CODE_FOR_nothing
)
397 if (optab_handler (add_optab
, qimode
) == CODE_FOR_nothing
)
404 /* Like optab_handler, but for widening_operations that have a
405 TO_MODE and a FROM_MODE. */
408 widening_optab_handler (optab op
, machine_mode to_mode
,
409 machine_mode from_mode
)
411 unsigned scode
= (op
<< 16) | to_mode
;
412 if (to_mode
!= from_mode
&& from_mode
!= VOIDmode
)
414 /* ??? Why does find_widening_optab_handler_and_mode attempt to
415 widen things that can't be widened? E.g. add_optab... */
416 if (op
> LAST_CONV_OPTAB
)
417 return CODE_FOR_nothing
;
418 scode
|= from_mode
<< 8;
420 return raw_optab_handler (scode
);
423 /* Find a widening optab even if it doesn't widen as much as we want.
424 E.g. if from_mode is HImode, and to_mode is DImode, and there is no
425 direct HI->SI insn, then return SI->DI, if that exists.
426 If PERMIT_NON_WIDENING is non-zero then this can be used with
427 non-widening optabs also. */
430 find_widening_optab_handler_and_mode (optab op
, machine_mode to_mode
,
431 machine_mode from_mode
,
432 int permit_non_widening
,
433 machine_mode
*found_mode
)
435 for (; (permit_non_widening
|| from_mode
!= to_mode
)
436 && GET_MODE_SIZE (from_mode
) <= GET_MODE_SIZE (to_mode
)
437 && from_mode
!= VOIDmode
;
438 from_mode
= GET_MODE_WIDER_MODE (from_mode
).else_void ())
440 enum insn_code handler
= widening_optab_handler (op
, to_mode
,
443 if (handler
!= CODE_FOR_nothing
)
446 *found_mode
= from_mode
;
451 return CODE_FOR_nothing
;
454 /* Return non-zero if a highpart multiply is supported of can be synthisized.
455 For the benefit of expand_mult_highpart, the return value is 1 for direct,
456 2 for even/odd widening, and 3 for hi/lo widening. */
459 can_mult_highpart_p (machine_mode mode
, bool uns_p
)
464 op
= uns_p
? umul_highpart_optab
: smul_highpart_optab
;
465 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
468 /* If the mode is an integral vector, synth from widening operations. */
469 if (GET_MODE_CLASS (mode
) != MODE_VECTOR_INT
)
472 nunits
= GET_MODE_NUNITS (mode
);
474 op
= uns_p
? vec_widen_umult_even_optab
: vec_widen_smult_even_optab
;
475 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
477 op
= uns_p
? vec_widen_umult_odd_optab
: vec_widen_smult_odd_optab
;
478 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
480 auto_vec_perm_indices
sel (nunits
);
481 for (i
= 0; i
< nunits
; ++i
)
482 sel
.quick_push (!BYTES_BIG_ENDIAN
484 + ((i
& 1) ? nunits
: 0));
485 if (can_vec_perm_p (mode
, false, &sel
))
490 op
= uns_p
? vec_widen_umult_hi_optab
: vec_widen_smult_hi_optab
;
491 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
493 op
= uns_p
? vec_widen_umult_lo_optab
: vec_widen_smult_lo_optab
;
494 if (optab_handler (op
, mode
) != CODE_FOR_nothing
)
496 auto_vec_perm_indices
sel (nunits
);
497 for (i
= 0; i
< nunits
; ++i
)
498 sel
.quick_push (2 * i
+ (BYTES_BIG_ENDIAN
? 0 : 1));
499 if (can_vec_perm_p (mode
, false, &sel
))
507 /* Return true if target supports vector masked load/store for mode. */
510 can_vec_mask_load_store_p (machine_mode mode
,
511 machine_mode mask_mode
,
514 optab op
= is_load
? maskload_optab
: maskstore_optab
;
516 unsigned int vector_sizes
;
518 /* If mode is vector mode, check it directly. */
519 if (VECTOR_MODE_P (mode
))
520 return convert_optab_handler (op
, mode
, mask_mode
) != CODE_FOR_nothing
;
522 /* Otherwise, return true if there is some vector mode with
523 the mask load/store supported. */
525 /* See if there is any chance the mask load or store might be
526 vectorized. If not, punt. */
528 if (!is_a
<scalar_mode
> (mode
, &smode
))
531 vmode
= targetm
.vectorize
.preferred_simd_mode (smode
);
532 if (!VECTOR_MODE_P (vmode
))
535 if ((targetm
.vectorize
.get_mask_mode
536 (GET_MODE_NUNITS (vmode
), GET_MODE_SIZE (vmode
)).exists (&mask_mode
))
537 && convert_optab_handler (op
, vmode
, mask_mode
) != CODE_FOR_nothing
)
540 vector_sizes
= targetm
.vectorize
.autovectorize_vector_sizes ();
541 while (vector_sizes
!= 0)
543 unsigned int cur
= 1 << floor_log2 (vector_sizes
);
544 vector_sizes
&= ~cur
;
545 if (cur
<= GET_MODE_SIZE (smode
))
547 unsigned int nunits
= cur
/ GET_MODE_SIZE (smode
);
548 if (mode_for_vector (smode
, nunits
).exists (&vmode
)
549 && VECTOR_MODE_P (vmode
)
550 && targetm
.vectorize
.get_mask_mode (nunits
, cur
).exists (&mask_mode
)
551 && convert_optab_handler (op
, vmode
, mask_mode
) != CODE_FOR_nothing
)
557 /* Return true if there is a compare_and_swap pattern. */
560 can_compare_and_swap_p (machine_mode mode
, bool allow_libcall
)
562 enum insn_code icode
;
564 /* Check for __atomic_compare_and_swap. */
565 icode
= direct_optab_handler (atomic_compare_and_swap_optab
, mode
);
566 if (icode
!= CODE_FOR_nothing
)
569 /* Check for __sync_compare_and_swap. */
570 icode
= optab_handler (sync_compare_and_swap_optab
, mode
);
571 if (icode
!= CODE_FOR_nothing
)
573 if (allow_libcall
&& optab_libfunc (sync_compare_and_swap_optab
, mode
))
576 /* No inline compare and swap. */
580 /* Return true if an atomic exchange can be performed. */
583 can_atomic_exchange_p (machine_mode mode
, bool allow_libcall
)
585 enum insn_code icode
;
587 /* Check for __atomic_exchange. */
588 icode
= direct_optab_handler (atomic_exchange_optab
, mode
);
589 if (icode
!= CODE_FOR_nothing
)
592 /* Don't check __sync_test_and_set, as on some platforms that
593 has reduced functionality. Targets that really do support
594 a proper exchange should simply be updated to the __atomics. */
596 return can_compare_and_swap_p (mode
, allow_libcall
);
599 /* Return true if an atomic load can be performed without falling back to
600 a compare-and-swap. */
603 can_atomic_load_p (machine_mode mode
)
605 enum insn_code icode
;
607 /* Does the target supports the load directly? */
608 icode
= direct_optab_handler (atomic_load_optab
, mode
);
609 if (icode
!= CODE_FOR_nothing
)
612 /* If the size of the object is greater than word size on this target,
613 then we assume that a load will not be atomic. Also see
614 expand_atomic_load. */
615 return GET_MODE_PRECISION (mode
) <= BITS_PER_WORD
;
618 /* Determine whether "1 << x" is relatively cheap in word_mode. */
621 lshift_cheap_p (bool speed_p
)
623 /* FIXME: This should be made target dependent via this "this_target"
624 mechanism, similar to e.g. can_copy_init_p in gcse.c. */
625 static bool init
[2] = { false, false };
626 static bool cheap
[2] = { true, true };
628 /* If the targer has no lshift in word_mode, the operation will most
629 probably not be cheap. ??? Does GCC even work for such targets? */
630 if (optab_handler (ashl_optab
, word_mode
) == CODE_FOR_nothing
)
635 rtx reg
= gen_raw_REG (word_mode
, 10000);
636 int cost
= set_src_cost (gen_rtx_ASHIFT (word_mode
, const1_rtx
, reg
),
638 cheap
[speed_p
] = cost
< COSTS_N_INSNS (3);
639 init
[speed_p
] = true;
642 return cheap
[speed_p
];