]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR target/52624
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Apr 2012 11:13:39 +0000 (11:13 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 11 Apr 2012 11:13:39 +0000 (11:13 +0000)
* doc/extend.texi (Other Builtins): Document __builtin_bswap16.
(PowerPC AltiVec/VSX Built-in Functions): Remove it.
* doc/md.texi (Standard Names): Add bswap.
* builtin-types.def (BT_UINT16): New primitive type.
(BT_FN_UINT16_UINT16): New function type.
* builtins.def (BUILT_IN_BSWAP16): New.
* builtins.c (expand_builtin_bswap): Add TARGET_MODE argument.
(expand_builtin) <BUILT_IN_BSWAP16>: New case.  Pass TARGET_MODE to
expand_builtin_bswap.
(fold_builtin_bswap): Add BUILT_IN_BSWAP16 case.
(fold_builtin_1): Likewise.
(is_inexpensive_builtin): Likewise.
* optabs.c (expand_unop): Deal with bswap in HImode specially.  Add
missing bits for bswap to libcall code.
* tree.c (build_common_tree_nodes): Build uint16_type_node.
* tree.h (enum tree_index): Add TI_UINT16_TYPE.
(uint16_type_node): New define.
* config/rs6000/rs6000-builtin.def (RS6000_BUILTIN_BSWAP_HI): Delete.
* config/rs6000/rs6000.c (rs6000_expand_builtin): Remove handling of
above builtin.
(rs6000_init_builtins): Likewise.
* config/rs6000/rs6000.md (bswaphi2): Add TARGET_POWERPC predicate.
c-family/
* c-common.h (uint16_type_node): Rename into...
(c_uint16_type_node): ...this.
* c-common.c (c_common_nodes_and_builtins): Adjust for above renaming.
* c-cppbuiltin.c (builtin_define_stdint_macros): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@186308 138bc75d-0d04-0410-961f-82ee72b054a4

21 files changed:
gcc/ChangeLog
gcc/builtin-types.def
gcc/builtins.c
gcc/builtins.def
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c-family/c-cppbuiltin.c
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/doc/extend.texi
gcc/doc/md.texi
gcc/optabs.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/builtin-bswap-1.c
gcc/testsuite/gcc.dg/builtin-bswap-4.c
gcc/testsuite/gcc.dg/builtin-bswap-5.c
gcc/testsuite/gcc.target/i386/builtin-bswap-4.c [new file with mode: 0644]
gcc/tree.c
gcc/tree.h

index 9f63cf54b2196e2329ca2978b6accaa6719f95e5..d0eaaf799c13092b7e997451513d5ada5e5d7a7a 100644 (file)
@@ -1,3 +1,29 @@
+2012-04-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/52624
+       * doc/extend.texi (Other Builtins): Document __builtin_bswap16.
+       (PowerPC AltiVec/VSX Built-in Functions): Remove it.
+       * doc/md.texi (Standard Names): Add bswap.
+       * builtin-types.def (BT_UINT16): New primitive type.
+       (BT_FN_UINT16_UINT16): New function type.
+       * builtins.def (BUILT_IN_BSWAP16): New.
+       * builtins.c (expand_builtin_bswap): Add TARGET_MODE argument.
+       (expand_builtin) <BUILT_IN_BSWAP16>: New case.  Pass TARGET_MODE to
+       expand_builtin_bswap.
+       (fold_builtin_bswap): Add BUILT_IN_BSWAP16 case.
+       (fold_builtin_1): Likewise.
+       (is_inexpensive_builtin): Likewise.
+       * optabs.c (expand_unop): Deal with bswap in HImode specially.  Add
+       missing bits for bswap to libcall code.
+       * tree.c (build_common_tree_nodes): Build uint16_type_node.
+       * tree.h (enum tree_index): Add TI_UINT16_TYPE.
+       (uint16_type_node): New define.
+       * config/rs6000/rs6000-builtin.def (RS6000_BUILTIN_BSWAP_HI): Delete.
+       * config/rs6000/rs6000.c (rs6000_expand_builtin): Remove handling of
+       above builtin.
+       (rs6000_init_builtins): Likewise.
+       * config/rs6000/rs6000.md (bswaphi2): Add TARGET_POWERPC predicate.
+
 2012-04-11  Tristan Gingold  <gingold@adacore.com>
 
        * doc/extend.texi (Type Attributes): Move paragraph.
index fd37c2ca83ae3d030235d97376efc756fb5b9000..d8e9e566694709919b3cc4e5a1633ebc4cf84f19 100644 (file)
@@ -76,6 +76,7 @@ DEF_PRIMITIVE_TYPE (BT_INT128, int128_integer_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT128, int128_unsigned_type_node)
 DEF_PRIMITIVE_TYPE (BT_INTMAX, intmax_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINTMAX, uintmax_type_node)
+DEF_PRIMITIVE_TYPE (BT_UINT16, uint16_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT32, uint32_type_node)
 DEF_PRIMITIVE_TYPE (BT_UINT64, uint64_type_node)
 DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1))
@@ -226,6 +227,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_VOID_PTRPTR, BT_VOID, BT_PTR_PTR)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT_UINT, BT_UINT, BT_UINT)
 DEF_FUNCTION_TYPE_1 (BT_FN_ULONG_ULONG, BT_ULONG, BT_ULONG)
 DEF_FUNCTION_TYPE_1 (BT_FN_ULONGLONG_ULONGLONG, BT_ULONGLONG, BT_ULONGLONG)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT16_UINT16, BT_UINT16, BT_UINT16)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT32_UINT32, BT_UINT32, BT_UINT32)
 DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_UINT64, BT_UINT64, BT_UINT64)
 
index 7afe61df505bbce993b29a8339f6daf4f6e95142..b47f2180527aebc69240270bd7b6bef22fd947f8 100644 (file)
@@ -4626,13 +4626,15 @@ expand_builtin_alloca (tree exp, bool cannot_accumulate)
   return result;
 }
 
-/* Expand a call to a bswap builtin with argument ARG0.  MODE
-   is the mode to expand with.  */
+/* Expand a call to bswap builtin in EXP.
+   Return NULL_RTX if a normal call should be emitted rather than expanding the
+   function in-line.  If convenient, the result should be placed in TARGET.
+   SUBTARGET may be used as the target for computing one of EXP's operands.  */
 
 static rtx
-expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
+expand_builtin_bswap (enum machine_mode target_mode, tree exp, rtx target,
+                     rtx subtarget)
 {
-  enum machine_mode mode;
   tree arg;
   rtx op0;
 
@@ -4640,14 +4642,18 @@ expand_builtin_bswap (tree exp, rtx target, rtx subtarget)
     return NULL_RTX;
 
   arg = CALL_EXPR_ARG (exp, 0);
-  mode = TYPE_MODE (TREE_TYPE (arg));
-  op0 = expand_expr (arg, subtarget, VOIDmode, EXPAND_NORMAL);
+  op0 = expand_expr (arg,
+                    subtarget && GET_MODE (subtarget) == target_mode
+                    ? subtarget : NULL_RTX,
+                    target_mode, EXPAND_NORMAL);
+  if (GET_MODE (op0) != target_mode)
+    op0 = convert_to_mode (target_mode, op0, 1);
 
-  target = expand_unop (mode, bswap_optab, op0, target, 1);
+  target = expand_unop (target_mode, bswap_optab, op0, target, 1);
 
   gcc_assert (target);
 
-  return convert_to_mode (mode, target, 0);
+  return convert_to_mode (target_mode, target, 1);
 }
 
 /* Expand a call to a unary builtin in EXP.
@@ -6077,10 +6083,10 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
       expand_stack_restore (CALL_EXPR_ARG (exp, 0));
       return const0_rtx;
 
+    case BUILT_IN_BSWAP16:
     case BUILT_IN_BSWAP32:
     case BUILT_IN_BSWAP64:
-      target = expand_builtin_bswap (exp, target, subtarget);
-
+      target = expand_builtin_bswap (target_mode, exp, target, subtarget);
       if (target)
        return target;
       break;
@@ -8169,7 +8175,7 @@ fold_builtin_bitop (tree fndecl, tree arg)
   return NULL_TREE;
 }
 
-/* Fold function call to builtin_bswap and the long and long long
+/* Fold function call to builtin_bswap and the short, long and long long
    variants.  Return NULL_TREE if no simplification can be made.  */
 static tree
 fold_builtin_bswap (tree fndecl, tree arg)
@@ -8182,15 +8188,15 @@ fold_builtin_bswap (tree fndecl, tree arg)
     {
       HOST_WIDE_INT hi, width, r_hi = 0;
       unsigned HOST_WIDE_INT lo, r_lo = 0;
-      tree type;
+      tree type = TREE_TYPE (TREE_TYPE (fndecl));
 
-      type = TREE_TYPE (arg);
       width = TYPE_PRECISION (type);
       lo = TREE_INT_CST_LOW (arg);
       hi = TREE_INT_CST_HIGH (arg);
 
       switch (DECL_FUNCTION_CODE (fndecl))
        {
+         case BUILT_IN_BSWAP16:
          case BUILT_IN_BSWAP32:
          case BUILT_IN_BSWAP64:
            {
@@ -8220,9 +8226,9 @@ fold_builtin_bswap (tree fndecl, tree arg)
        }
 
       if (width < HOST_BITS_PER_WIDE_INT)
-       return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), r_lo);
+       return build_int_cst (type, r_lo);
       else
-       return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), r_lo, r_hi);
+       return build_int_cst_wide (type, r_lo, r_hi);
     }
 
   return NULL_TREE;
@@ -10575,6 +10581,7 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
     CASE_FLT_FN (BUILT_IN_LLRINT):
       return fold_fixed_mathfn (loc, fndecl, arg0);
 
+    case BUILT_IN_BSWAP16:
     case BUILT_IN_BSWAP32:
     case BUILT_IN_BSWAP64:
       return fold_builtin_bswap (fndecl, arg0);
@@ -14339,6 +14346,7 @@ is_inexpensive_builtin (tree decl)
       case BUILT_IN_ABS:
       case BUILT_IN_ALLOCA:
       case BUILT_IN_ALLOCA_WITH_ALIGN:
+      case BUILT_IN_BSWAP16:
       case BUILT_IN_BSWAP32:
       case BUILT_IN_BSWAP64:
       case BUILT_IN_CLZ:
index 0cba2feea63d0d6896ce70fcf6da825ea8c8e8a5..d03e41092b8744bc0ee31722652959325a4109f0 100644 (file)
@@ -628,6 +628,7 @@ DEF_GCC_BUILTIN        (BUILT_IN_AGGREGATE_INCOMING_ADDRESS, "aggregate_incoming
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_ALLOCA, "alloca", BT_FN_PTR_SIZE, ATTR_MALLOC_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_APPLY, "apply", BT_FN_PTR_PTR_FN_VOID_VAR_PTR_SIZE, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_LEAF_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_BSWAP16, "bswap16", BT_FN_UINT16_UINT16, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LEAF_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
index 558c6a736e97ca7d38b82fbf5ba1442e9edd5d1e..121d94a11a3dcef4b209082d6060011529c14f56 100644 (file)
@@ -1,3 +1,11 @@
+2012-04-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+       PR target/52624
+       * c-common.h (uint16_type_node): Rename into...
+       (c_uint16_type_node): ...this.
+       * c-common.c (c_common_nodes_and_builtins): Adjust for above renaming.
+       * c-cppbuiltin.c (builtin_define_stdint_macros): Likewise.
+
 2012-04-10  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        * c-common.c (warn_if_unused_value): Move definition to here.
index a9e7ec1d14dcf352bef7bd12da2743cc8bf6f411..a08db464dfd4a88fb280c05cf763162192b77b5e 100644 (file)
@@ -5087,7 +5087,7 @@ c_common_nodes_and_builtins (void)
     uint8_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT8_TYPE)));
   if (UINT16_TYPE)
-    uint16_type_node =
+    c_uint16_type_node =
       TREE_TYPE (identifier_global_value (c_get_ident (UINT16_TYPE)));
   if (UINT32_TYPE)
     c_uint32_type_node =
index cab7b43966191c5c916d49ac25e11b91433dc938..dd411032272e2c3ff54444ee0548cc5a21c9e497 100644 (file)
@@ -390,7 +390,7 @@ extern const unsigned int num_c_common_reswords;
 #define int32_type_node                        c_global_trees[CTI_INT32_TYPE]
 #define int64_type_node                        c_global_trees[CTI_INT64_TYPE]
 #define uint8_type_node                        c_global_trees[CTI_UINT8_TYPE]
-#define uint16_type_node               c_global_trees[CTI_UINT16_TYPE]
+#define c_uint16_type_node             c_global_trees[CTI_UINT16_TYPE]
 #define c_uint32_type_node             c_global_trees[CTI_UINT32_TYPE]
 #define c_uint64_type_node             c_global_trees[CTI_UINT64_TYPE]
 #define int_least8_type_node           c_global_trees[CTI_INT_LEAST8_TYPE]
index 49804f98146075e02af4e7bdfc9515abda31fcab..920154a73c8a170c26ba2890b12a00fd2379ca07 100644 (file)
@@ -448,8 +448,8 @@ builtin_define_stdint_macros (void)
     builtin_define_type_max ("__INT64_MAX__", int64_type_node);
   if (uint8_type_node)
     builtin_define_type_max ("__UINT8_MAX__", uint8_type_node);
-  if (uint16_type_node)
-    builtin_define_type_max ("__UINT16_MAX__", uint16_type_node);
+  if (c_uint16_type_node)
+    builtin_define_type_max ("__UINT16_MAX__", c_uint16_type_node);
   if (c_uint32_type_node)
     builtin_define_type_max ("__UINT32_MAX__", c_uint32_type_node);
   if (c_uint64_type_node)
index 776350bb5c06e31bd2ea22139045dfc9c2b54333..2fd51af458f98f2e788c5e550978cc79c1f08168 100644 (file)
@@ -1430,9 +1430,6 @@ BU_SPECIAL_X (RS6000_BUILTIN_RSQRT, "__builtin_rsqrt", RS6000_BTM_FRSQRTE,
 BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES,
              RS6000_BTC_FP)
 
-BU_SPECIAL_X (RS6000_BUILTIN_BSWAP_HI, "__builtin_bswap16", RS6000_BTM_POWERPC,
-             RS6000_BTC_MEM)
-
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_POWERPC,
              RS6000_BTC_MISC)
index b6054b302c81fd8fea2590e2afbe8b33e264bffd..fa882de429bcbd01aad2c3cf0ab30da206c2702e 100644 (file)
@@ -11381,9 +11381,6 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
     case RS6000_BUILTIN_RSQRT:
       return rs6000_expand_unop_builtin (CODE_FOR_rsqrtdf2, exp, target);
 
-    case RS6000_BUILTIN_BSWAP_HI:
-      return rs6000_expand_unop_builtin (CODE_FOR_bswaphi2, exp, target);
-
     case POWER7_BUILTIN_BPERMD:
       return rs6000_expand_binop_builtin (((TARGET_64BIT)
                                           ? CODE_FOR_bpermd_di
@@ -11673,12 +11670,6 @@ rs6000_init_builtins (void)
                                 POWER7_BUILTIN_BPERMD, "__builtin_bpermd");
   def_builtin ("__builtin_bpermd", ftype, POWER7_BUILTIN_BPERMD);
 
-      /* Don't use builtin_function_type here, as it maps HI/QI to SI.  */
-  ftype = build_function_type_list (unsigned_intHI_type_node,
-                                   unsigned_intHI_type_node,
-                                   NULL_TREE);
-  def_builtin ("__builtin_bswap16", ftype, RS6000_BUILTIN_BSWAP_HI);
-
 #if TARGET_XCOFF
   /* AIX libm provides clog as __clog.  */
   if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
index 22207bbf2b25ee14da8c5608ceb117a0d0a0e8cd..1f5085da1ca7b3569e91f64a48b2f98aeefc9264 100644 (file)
                   (bswap:HI
                    (match_operand:HI 1 "reg_or_mem_operand" "")))
              (clobber (match_scratch:SI 2 ""))])]
-  ""
+  "TARGET_POWERPC"
 {
   if (!REG_P (operands[0]) && !REG_P (operands[1]))
     operands[1] = force_reg (HImode, operands[1]);
index c33ec66f65ed2924beed93568770ae4e9af171fb..dd08845fb9bf0f662a6e260236c71a41ec33b7bc 100644 (file)
@@ -8535,12 +8535,17 @@ Similar to @code{__builtin_powi}, except the argument and return types
 are @code{long double}.
 @end deftypefn
 
-@deftypefn {Built-in Function} int32_t __builtin_bswap32 (int32_t x)
+@deftypefn {Built-in Function} int16_t __builtin_bswap16 (int16_t x)
 Returns @var{x} with the order of the bytes reversed; for example,
-@code{0xaabbccdd} becomes @code{0xddccbbaa}.  Byte here always means
+@code{0xaabb} becomes @code{0xbbaa}.  Byte here always means
 exactly 8 bits.
 @end deftypefn
 
+@deftypefn {Built-in Function} int32_t __builtin_bswap32 (int32_t x)
+Similar to @code{__builtin_bswap16}, except the argument and return types
+are 32-bit.
+@end deftypefn
+
 @deftypefn {Built-in Function} int64_t __builtin_bswap64 (int64_t x)
 Similar to @code{__builtin_bswap32}, except the argument and return types
 are 64-bit.
@@ -13426,7 +13431,6 @@ float __builtin_rsqrtf (float);
 double __builtin_recipdiv (double, double);
 double __builtin_rsqrt (double);
 long __builtin_bpermd (long, long);
-int __builtin_bswap16 (int);
 @end smallexample
 
 The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
index c4eb355e253719551b394c03acac35645a773fcb..bca84a72ce5c464ff61dad7e8c32c7df43e90535 100644 (file)
@@ -4736,6 +4736,10 @@ Other shift and rotate instructions, analogous to the
 Vector shift and rotate instructions that take vectors as operand 2
 instead of a scalar type.
 
+@cindex @code{bswap@var{m}2} instruction pattern
+@item @samp{bswap@var{m}2}
+Reverse the order of bytes of operand 1 and store the result in operand 0.
+
 @cindex @code{neg@var{m}2} instruction pattern
 @cindex @code{ssneg@var{m}2} instruction pattern
 @cindex @code{usneg@var{m}2} instruction pattern
index 565db428045c74cf1f6064fe4360d1a23874eca7..080061a1f57b32bba0259e4000067b1d264a7de8 100644 (file)
@@ -3030,6 +3030,47 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
   /* Widening (or narrowing) bswap needs special treatment.  */
   if (unoptab == bswap_optab)
     {
+      /* HImode is special because in this mode BSWAP is equivalent to ROTATE
+        or ROTATERT.  First try these directly; if this fails, then try the
+        obvious pair of shifts with allowed widening, as this will probably
+        be always more efficient than the other fallback methods.  */
+      if (mode == HImode)
+       {
+         rtx last, temp1, temp2;
+
+         if (optab_handler (rotl_optab, mode) != CODE_FOR_nothing)
+           {
+             temp = expand_binop (mode, rotl_optab, op0, GEN_INT (8), target,
+                                  unsignedp, OPTAB_DIRECT);
+             if (temp)
+               return temp;
+            }
+
+         if (optab_handler (rotr_optab, mode) != CODE_FOR_nothing)
+           {
+             temp = expand_binop (mode, rotr_optab, op0, GEN_INT (8), target,
+                                  unsignedp, OPTAB_DIRECT);
+             if (temp)
+               return temp;
+           }
+
+         last = get_last_insn ();
+
+         temp1 = expand_binop (mode, ashl_optab, op0, GEN_INT (8), NULL_RTX,
+                               unsignedp, OPTAB_WIDEN);
+         temp2 = expand_binop (mode, lshr_optab, op0, GEN_INT (8), NULL_RTX,
+                               unsignedp, OPTAB_WIDEN);
+         if (temp1 && temp2)
+           {
+             temp = expand_binop (mode, ior_optab, temp1, temp2, target,
+                                  unsignedp, OPTAB_WIDEN);
+             if (temp)
+               return temp;
+           }
+
+         delete_insns_since (last);
+       }
+
       temp = widen_bswap (mode, op0, target);
       if (temp)
        return temp;
@@ -3222,10 +3263,10 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
              /* For certain operations, we need not actually extend
                 the narrow operand, as long as we will truncate the
                 results to the same narrowness.  */
-
              xop0 = widen_operand (xop0, wider_mode, mode, unsignedp,
                                    (unoptab == neg_optab
-                                    || unoptab == one_cmpl_optab)
+                                    || unoptab == one_cmpl_optab
+                                    || unoptab == bswap_optab)
                                    && mclass == MODE_INT);
 
              temp = expand_unop (wider_mode, unoptab, xop0, NULL_RTX,
@@ -3240,6 +3281,20 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
                                              - GET_MODE_PRECISION (mode)),
                                     target, true, OPTAB_DIRECT);
 
+             /* Likewise for bswap.  */
+             if (unoptab == bswap_optab && temp != 0)
+               {
+                 gcc_assert (GET_MODE_PRECISION (wider_mode)
+                             == GET_MODE_BITSIZE (wider_mode)
+                             && GET_MODE_PRECISION (mode)
+                                == GET_MODE_BITSIZE (mode));
+
+                 temp = expand_shift (RSHIFT_EXPR, wider_mode, temp,
+                                      GET_MODE_BITSIZE (wider_mode)
+                                      - GET_MODE_BITSIZE (mode),
+                                      NULL_RTX, true);
+               }
+
              if (temp)
                {
                  if (mclass != MODE_INT)
index 61d83ffeedc5d0918fbe102f2e05c32a70782f5b..5c16617adfb1cac7be8837030b0e36f419cafc82 100644 (file)
@@ -1,3 +1,10 @@
+2012-04-11  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * gcc.dg/builtin-bswap-1.c: Test __builtin_bswap16 & __builtin_bswap64.
+       * gcc.dg/builtin-bswap-4.c: Test __builtin_bswap16.
+       * gcc.dg/builtin-bswap-5.c: Likewise.
+       * gcc.target/i386/builtin-bswap-4.c: New test.
+
 2012-04-11  Manuel López-Ibáñez  <manu@gcc.gnu.org>
 
        PR 24985
index 6b4a805536cef4bd43c66429ebdc66685c7c95db..724ba1e9847e9bac2e241f17977be1cfa1666fa1 100644 (file)
@@ -5,11 +5,29 @@
 
 #include <stdint.h>
 
-uint32_t foo (uint32_t a)
+uint16_t foo16 (uint16_t a)
 {
-  int b;
+  uint16_t b;
+
+  b = __builtin_bswap16 (a);
+
+  return b;
+}
+
+uint32_t foo32 (uint32_t a)
+{
+  uint32_t b;
 
   b = __builtin_bswap32 (a);
 
   return b;
 }
+
+uint64_t foo64 (uint64_t a)
+{
+  uint64_t b;
+
+  b = __builtin_bswap64 (a);
+
+  return b;
+}
index 03e190ad782f6fa907e51c22a3b5ee49331e00a7..da8ee68cd519b2f4c551887102f6bc09676949f4 100644 (file)
     return result;                                                     \
   }                                                                    \
 
+MAKE_FUN(16, uint16_t);
 MAKE_FUN(32, uint32_t);
 MAKE_FUN(64, uint64_t);
 
 extern void abort (void);
 
+#define NUMS16                                 \
+  {                                            \
+    0x0000,                                    \
+    0x1122,                                    \
+    0xffff,                                    \
+  }
+
 #define NUMS32                                 \
   {                                            \
     0x00000000UL,                              \
@@ -35,6 +43,9 @@ extern void abort (void);
     0xffffffffffffffffULL,                     \
   }
 
+uint16_t uint16_ts[] =
+  NUMS16;
+
 uint32_t uint32_ts[] =
   NUMS32;
 
@@ -48,6 +59,10 @@ main (void)
 {
   int i;
 
+  for (i = 0; i < N(uint16_ts); i++)
+    if (__builtin_bswap16 (uint16_ts[i]) != my_bswap16 (uint16_ts[i]))
+      abort ();
+
   for (i = 0; i < N(uint32_ts); i++)
     if (__builtin_bswap32 (uint32_ts[i]) != my_bswap32 (uint32_ts[i]))
       abort ();
index ccac9663334decf0eca760e6d33df97113398990..b29931e4e10d35048f76ea14bb2603227fe1ecc5 100644 (file)
@@ -6,6 +6,9 @@ main (void)
   /* Test constant folding.  */
   extern void link_error (void);
 
+  if (__builtin_bswap16(0xaabb) != 0xbbaa)
+    link_error ();
+
   if (__builtin_bswap32(0xaabbccdd) != 0xddccbbaa)
     link_error ();
 
diff --git a/gcc/testsuite/gcc.target/i386/builtin-bswap-4.c b/gcc/testsuite/gcc.target/i386/builtin-bswap-4.c
new file mode 100644 (file)
index 0000000..65198ae
--- /dev/null
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "bswap\[ \t\]" } } */
+
+short foo (short x)
+{
+  return __builtin_bswap16 (x);
+}
index 7c7e43a5a8817e0349f9303e2fe3471312b5a47c..e5a33de51ff9566de1ba2f4a49c8b954b3c923e0 100644 (file)
@@ -9388,6 +9388,7 @@ build_common_tree_nodes (bool signed_char, bool short_double)
   integer_ptr_type_node = build_pointer_type (integer_type_node);
 
   /* Fixed size integer types.  */
+  uint16_type_node = build_nonstandard_integer_type (16, true);
   uint32_type_node = build_nonstandard_integer_type (32, true);
   uint64_type_node = build_nonstandard_integer_type (64, true);
 
index c3fbde99b568fb45b053443ba8624cb8dc73a5c5..809017667d6ac5f0ab7e4e2b5dd95a87877b3e61 100644 (file)
@@ -3747,6 +3747,7 @@ enum tree_index
   TI_UINTDI_TYPE,
   TI_UINTTI_TYPE,
 
+  TI_UINT16_TYPE,
   TI_UINT32_TYPE,
   TI_UINT64_TYPE,
 
@@ -3902,6 +3903,7 @@ extern GTY(()) tree global_trees[TI_MAX];
 #define unsigned_intDI_type_node       global_trees[TI_UINTDI_TYPE]
 #define unsigned_intTI_type_node       global_trees[TI_UINTTI_TYPE]
 
+#define uint16_type_node               global_trees[TI_UINT16_TYPE]
 #define uint32_type_node               global_trees[TI_UINT32_TYPE]
 #define uint64_type_node               global_trees[TI_UINT64_TYPE]