aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/builtin-types.def4
-rw-r--r--gcc/builtins.c2
-rw-r--r--gcc/builtins.def2
-rw-r--r--gcc/doc/extend.texi10
-rw-r--r--gcc/fold-const-call.c1
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/optabs.c5
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-10.c8
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-11.c51
-rw-r--r--gcc/testsuite/gcc.dg/builtin-bswap-12.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/builtin-bswap-5.c8
-rw-r--r--gcc/tree-core.h1
-rw-r--r--gcc/tree-ssa-ccp.c1
-rw-r--r--gcc/tree-vect-stmts.c5
-rw-r--r--gcc/tree.c2
-rw-r--r--gcc/tree.h1
16 files changed, 125 insertions, 5 deletions
diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def
index c7aa691..c46b1bc 100644
--- a/gcc/builtin-types.def
+++ b/gcc/builtin-types.def
@@ -73,6 +73,9 @@ DEF_PRIMITIVE_TYPE (BT_UINT8, unsigned_char_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_UINT128, uint128_type_node
+ ? uint128_type_node
+ : error_mark_node)
DEF_PRIMITIVE_TYPE (BT_WORD, (*lang_hooks.types.type_for_mode) (word_mode, 1))
DEF_PRIMITIVE_TYPE (BT_UNWINDWORD, (*lang_hooks.types.type_for_mode)
(targetm.unwind_word_mode (), 1))
@@ -300,6 +303,7 @@ DEF_FUNCTION_TYPE_1 (BT_FN_UINT8_FLOAT, BT_UINT8, BT_FLOAT)
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)
+DEF_FUNCTION_TYPE_1 (BT_FN_UINT128_UINT128, BT_UINT128, BT_UINT128)
DEF_FUNCTION_TYPE_1 (BT_FN_UINT64_FLOAT, BT_UINT64, BT_FLOAT)
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_INT, BT_BOOL, BT_INT)
DEF_FUNCTION_TYPE_1 (BT_FN_BOOL_PTR, BT_BOOL, BT_PTR)
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 53bae59..f7bb87e 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -7988,6 +7988,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
case BUILT_IN_BSWAP16:
case BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP64:
+ case BUILT_IN_BSWAP128:
target = expand_builtin_bswap (target_mode, exp, target, subtarget);
if (target)
return target;
@@ -11704,6 +11705,7 @@ is_inexpensive_builtin (tree decl)
case BUILT_IN_BSWAP16:
case BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP64:
+ case BUILT_IN_BSWAP128:
case BUILT_IN_CLZ:
case BUILT_IN_CLZIMAX:
case BUILT_IN_CLZL:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index fa8b064..ee67ac1 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -834,6 +834,8 @@ DEF_GCC_BUILTIN (BUILT_IN_APPLY_ARGS, "apply_args", BT_FN_PTR_VAR, ATTR_L
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_GCC_BUILTIN (BUILT_IN_BSWAP128, "bswap128", BT_FN_UINT128_UINT128, ATTR_CONST_NOTHROW_LEAF_LIST)
+
DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LEAF_LIST)
/* [trans-mem]: Adjust BUILT_IN_TM_CALLOC if BUILT_IN_CALLOC is changed. */
DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_WARN_UNUSED_RESULT_SIZE_1_2_NOTHROW_LEAF_LIST)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index a2ebef8..cced19d 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13784,14 +13784,20 @@ exactly 8 bits.
@deftypefn {Built-in Function} uint32_t __builtin_bswap32 (uint32_t x)
Similar to @code{__builtin_bswap16}, except the argument and return types
-are 32 bit.
+are 32-bit.
@end deftypefn
@deftypefn {Built-in Function} uint64_t __builtin_bswap64 (uint64_t x)
Similar to @code{__builtin_bswap32}, except the argument and return types
-are 64 bit.
+are 64-bit.
@end deftypefn
+@deftypefn {Built-in Function} uint128_t __builtin_bswap128 (uint128_t x)
+Similar to @code{__builtin_bswap64}, except the argument and return types
+are 128-bit. Only supported on targets when 128-bit types are supported.
+@end deftypefn
+
+
@deftypefn {Built-in Function} Pmode __builtin_extend_pointer (void * x)
On targets where the user visible pointer size is smaller than the size
of an actual hardware address this function returns the extended user
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 29dab0f..c9e368d 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -1033,6 +1033,7 @@ fold_const_call_ss (wide_int *result, combined_fn fn, const wide_int_ref &arg,
case CFN_BUILT_IN_BSWAP16:
case CFN_BUILT_IN_BSWAP32:
case CFN_BUILT_IN_BSWAP64:
+ case CFN_BUILT_IN_BSWAP128:
*result = wide_int::from (arg, precision, TYPE_SIGN (arg_type)).bswap ();
return true;
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f054871..212d0ba 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -13794,8 +13794,10 @@ tree_call_nonnegative_warnv_p (tree type, combined_fn fn, tree arg0, tree arg1,
CASE_CFN_POPCOUNT:
CASE_CFN_CLZ:
CASE_CFN_CLRSB:
+ case CFN_BUILT_IN_BSWAP16:
case CFN_BUILT_IN_BSWAP32:
case CFN_BUILT_IN_BSWAP64:
+ case CFN_BUILT_IN_BSWAP128:
/* Always true. */
return true;
diff --git a/gcc/optabs.c b/gcc/optabs.c
index d85ce47..7a4ec1e 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2889,8 +2889,11 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
if (temp)
return temp;
+ /* We do not provide a 128-bit bswap in libgcc so force the use of
+ a double bswap for 64-bit targets. */
if (GET_MODE_SIZE (int_mode) == 2 * UNITS_PER_WORD
- && optab_handler (unoptab, word_mode) != CODE_FOR_nothing)
+ && (UNITS_PER_WORD == 64
+ || optab_handler (unoptab, word_mode) != CODE_FOR_nothing))
{
temp = expand_doubleword_bswap (mode, op0, target);
if (temp)
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-10.c b/gcc/testsuite/gcc.dg/builtin-bswap-10.c
new file mode 100644
index 0000000..6c8a39f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-10.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target { ilp32 } } } */
+/* { dg-options "" } */
+/* { dg-final { scan-assembler "__builtin_" } } */
+
+int foo (int x)
+{
+ return __builtin_bswap128 (x); /* { dg-warning "implicit declaration" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-11.c b/gcc/testsuite/gcc.dg/builtin-bswap-11.c
new file mode 100644
index 0000000..3fedcf1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-11.c
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-options "-Wall" } */
+
+#include <stdint.h>
+
+#define MAKE_FUN(suffix, type) \
+ type my_bswap##suffix(type x) { \
+ type result = 0; \
+ int shift; \
+ for (shift = 0; shift < 8 * sizeof (type); shift += 8) \
+ { \
+ result <<= 8; \
+ result |= (x >> shift) & 0xff; \
+ } \
+ return result; \
+ } \
+
+MAKE_FUN(128, __uint128_t);
+
+extern void abort (void);
+
+typedef union
+{
+ struct { uint64_t lo; uint64_t hi; } s;
+ __uint128_t n;
+} u;
+
+#define NUMS128 \
+ { \
+ { .s = { 0x0000000000000000ULL, 0x1122334455667788ULL } }, \
+ { .s = { 0x1122334455667788ULL, 0xffffffffffffffffULL } }, \
+ { .s = { 0xffffffffffffffffULL, 0x0000000000000000ULL } } \
+ }
+
+u uint128_ts[] = NUMS128;
+
+#define N(table) (sizeof (table) / sizeof (table[0]))
+
+int
+main (void)
+{
+ int i;
+
+ for (i = 0; i < N(uint128_ts); i++)
+ if (__builtin_bswap128 (uint128_ts[i].n) != my_bswap128 (uint128_ts[i].n))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-bswap-12.c b/gcc/testsuite/gcc.dg/builtin-bswap-12.c
new file mode 100644
index 0000000..8ff65d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-bswap-12.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int128 } */
+/* { dg-require-effective-target stdint_types } */
+/* { dg-options "-O" } */
+
+#include <stdint.h>
+
+typedef union
+{
+ struct { uint64_t lo; uint64_t hi; } s;
+ __uint128_t n;
+} u;
+
+int
+main (void)
+{
+ /* Test constant folding. */
+ extern void link_error (void);
+
+ const u U1 = { .s = { 0x1122334455667788ULL, 0xffffffffffffffffULL } };
+ const u U2 = { .s = { 0xffffffffffffffffULL, 0x8877665544332211ULL } };
+
+ if (__builtin_bswap128 (U1.n) != U2.n)
+ link_error ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/builtin-bswap-5.c b/gcc/testsuite/gcc.target/i386/builtin-bswap-5.c
new file mode 100644
index 0000000..a73a870
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/builtin-bswap-5.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int128 } */
+/* { dg-final { scan-assembler-not "call" } } */
+
+__uint128_t foo (__uint128_t x)
+{
+ return __builtin_bswap128 (x);
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 0309148..8c5a2e3 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -600,6 +600,7 @@ enum tree_index {
TI_UINT16_TYPE,
TI_UINT32_TYPE,
TI_UINT64_TYPE,
+ TI_UINT128_TYPE,
TI_VOID,
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index be6647d..e9d2f4b 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2002,6 +2002,7 @@ evaluate_stmt (gimple *stmt)
case BUILT_IN_BSWAP16:
case BUILT_IN_BSWAP32:
case BUILT_IN_BSWAP64:
+ case BUILT_IN_BSWAP128:
val = get_value_for_expr (gimple_call_arg (stmt, 0), true);
if (val.lattice_val == UNDEFINED)
break;
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 35043ec..2f92bb5 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3003,7 +3003,7 @@ vect_get_data_ptr_increment (vec_info *vinfo,
return iv_step;
}
-/* Check and perform vectorization of BUILT_IN_BSWAP{16,32,64}. */
+/* Check and perform vectorization of BUILT_IN_BSWAP{16,32,64,128}. */
static bool
vectorizable_bswap (vec_info *vinfo,
@@ -3385,7 +3385,8 @@ vectorizable_call (vec_info *vinfo,
else if (modifier == NONE
&& (gimple_call_builtin_p (stmt, BUILT_IN_BSWAP16)
|| gimple_call_builtin_p (stmt, BUILT_IN_BSWAP32)
- || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP64)))
+ || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP64)
+ || gimple_call_builtin_p (stmt, BUILT_IN_BSWAP128)))
return vectorizable_bswap (vinfo, stmt_info, gsi, vec_stmt, slp_node,
slp_op, vectype_in, cost_vec);
else
diff --git a/gcc/tree.c b/gcc/tree.c
index ea66924..2cc9e4f 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10350,6 +10350,8 @@ build_common_tree_nodes (bool signed_char)
uint16_type_node = make_or_reuse_type (16, 1);
uint32_type_node = make_or_reuse_type (32, 1);
uint64_type_node = make_or_reuse_type (64, 1);
+ if (targetm.scalar_mode_supported_p (TImode))
+ uint128_type_node = make_or_reuse_type (128, 1);
/* Decimal float types. */
if (targetm.decimal_float_supported_p ())
diff --git a/gcc/tree.h b/gcc/tree.h
index 0c8585f..21a96b2 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4037,6 +4037,7 @@ tree_strip_any_location_wrapper (tree exp)
#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]
+#define uint128_type_node global_trees[TI_UINT128_TYPE]
#define void_node global_trees[TI_VOID]