diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/builtin-types.def | 4 | ||||
-rw-r--r-- | gcc/builtins.c | 2 | ||||
-rw-r--r-- | gcc/builtins.def | 2 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 10 | ||||
-rw-r--r-- | gcc/fold-const-call.c | 1 | ||||
-rw-r--r-- | gcc/fold-const.c | 2 | ||||
-rw-r--r-- | gcc/optabs.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-bswap-10.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-bswap-11.c | 51 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/builtin-bswap-12.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/builtin-bswap-5.c | 8 | ||||
-rw-r--r-- | gcc/tree-core.h | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-ccp.c | 1 | ||||
-rw-r--r-- | gcc/tree-vect-stmts.c | 5 | ||||
-rw-r--r-- | gcc/tree.c | 2 | ||||
-rw-r--r-- | gcc/tree.h | 1 |
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 @@ -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 ()) @@ -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] |