break;
case 32:
if (builtin_decl_explicit_p (BUILT_IN_BSWAP32)
- && (optab_handler (bswap_optab, SImode) != CODE_FOR_nothing
- /* widen_bswap_or_bitreverse can implement 32-bit bswap
- using bswapdi2 and shift. */
- || optab_handler (bswap_optab, DImode) != CODE_FOR_nothing))
+ && can_open_code_p (bswap_optab, SImode))
{
load_type = uint32_type_node;
fndecl = builtin_decl_explicit (BUILT_IN_BSWAP32);
break;
case 64:
if (builtin_decl_explicit_p (BUILT_IN_BSWAP64)
- && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing
- /* expand_doubleword_bswap_or_bitreverse can use 2 bswapsi2
- expanders on 32-bit targets. */
- || (word_mode == SImode
- && builtin_decl_explicit_p (BUILT_IN_BSWAP32)
- && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing)))
+ && can_open_code_p (bswap_optab, DImode))
{
load_type = uint64_type_node;
fndecl = builtin_decl_explicit (BUILT_IN_BSWAP64);
tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE;
bswap32_p = (builtin_decl_explicit_p (BUILT_IN_BSWAP32)
- && (optab_handler (bswap_optab, SImode) != CODE_FOR_nothing
- /* widen_bswap_or_bitreverse can implement 32-bit bswap
- using bswapdi2 and shift. */
- || (optab_handler (bswap_optab, DImode)
- != CODE_FOR_nothing)));
+ && can_open_code_p (bswap_optab, SImode));
bswap64_p = (builtin_decl_explicit_p (BUILT_IN_BSWAP64)
- && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing
- /* expand_doubleword_bswap_or_bitreverse can use 2 bswapsi2
- expanders on 32-bit targets. */
- || (bswap32_p && word_mode == SImode)));
+ && can_open_code_p (bswap_optab, DImode));
/* Determine the argument type of the builtins. The code later on
assumes that the return and argument type are the same. */
break;
case 32:
if (builtin_decl_explicit_p (BUILT_IN_BSWAP32)
- && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing)
+ && can_open_code_p (bswap_optab, SImode))
break;
return false;
case 64:
if (builtin_decl_explicit_p (BUILT_IN_BSWAP64)
- && (optab_handler (bswap_optab, DImode) != CODE_FOR_nothing
- || (word_mode == SImode
- && builtin_decl_explicit_p (BUILT_IN_BSWAP32)
- && optab_handler (bswap_optab, SImode) != CODE_FOR_nothing)))
+ && can_open_code_p (bswap_optab, DImode))
break;
return false;
default:
&& can_implement_p (op == neg_optab ? xor_optab : and_optab, new_mode))
return true;
+ scalar_int_mode int_mode;
+ if (op == bswap_optab && is_a<scalar_int_mode> (mode, &int_mode))
+ {
+ /* widen_bswap_or_bitreverse can implement smaller bswaps using
+ wider bswaps and a shift. */
+ opt_scalar_int_mode wider_mode_iter;
+ FOR_EACH_WIDER_MODE (wider_mode_iter, int_mode)
+ if (optab_handler (op, wider_mode_iter.require ()) != CODE_FOR_nothing)
+ return true;
+
+ /* expand_doubleword_bswap_or_bitreverse can use 2 word bswaps to
+ implement a doubleword bswap. */
+ if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
+ && optab_handler (op, word_mode) != CODE_FOR_nothing)
+ return true;
+ }
+
return false;
}