aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJulian Brown <julian@codesourcery.com>2021-06-09 06:18:23 -0700
committerJulian Brown <julian@codesourcery.com>2021-06-29 08:19:56 -0700
commita8a730cd99184e62c4d026b8c775b96589a9c262 (patch)
treedbdae551485ac2725318d60267b2cb95fccf95e9 /gcc
parent0c06e46a81d86d70d788ca1a93d27b6902bd4dc1 (diff)
downloadgcc-a8a730cd99184e62c4d026b8c775b96589a9c262.zip
gcc-a8a730cd99184e62c4d026b8c775b96589a9c262.tar.gz
gcc-a8a730cd99184e62c4d026b8c775b96589a9c262.tar.bz2
amdgcn: Enable support for TImode for AMD GCN
This patch enables support for TImode for AMD GCN, the lack of which is currently causing a number of test failures for the target and which is also needed to support "omp_depend_kind" for OpenMP 5.0, since that is implemented as a 128-bit integer. Several libgcc support routines are built by default for the "word size" of a machine, and also for "2 * word size" of the machine. The libgcc build for AMD GCN is changed so that it builds for a "word size" of 64 bits, in order to better match the (64-bit) host compiler. However it isn't really true that we have 64-bit words -- GCN has 32-bit registers, so changing UNITS_PER_WORD unconditionally would be the wrong thing to do. Changing this setting for libgcc (only) means that support routines are built for "single word" operations that are DImode (64 bits), and those for "double word" operations are built for TImode (128 bits). That leaves some gaps regarding previous operations that were built for a "single word" size of 32 bits and a "double word" size of 64 bits (generic code doesn't cover both alternatives for all operations that might be needed). Those gaps are filled in by this patch, or by the preceding patches in the series. 2021-06-18 Julian Brown <julian@codesourcery.com> gcc/ * config/gcn/gcn.c (gcn_init_libfuncs): New function. (TARGET_INIT_LIBFUNCS): Define target hook using above function. * config/gcn/gcn.h (UNITS_PER_WORD): Define to 8 for IN_LIBGCC2, 4 otherwise. (LIBGCC2_UNITS_PER_WORD, BITS_PER_WORD): Remove definitions. (MAX_FIXED_MODE_SIZE): Change to 128. libgcc/ * config/gcn/lib2-bswapti2.c: New file. * config/gcn/lib2-divmod-di.c: New file. * config/gcn/lib2-gcn.h (DItype, UDItype, TItype, UTItype): Add typedefs. (__divdi3, __moddi3, __udivdi3, __umoddi3): Add prototypes. * config/gcn/t-amdgcn (LIB2ADD): Add lib2-divmod-di.c and lib2-bswapti2.c.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/gcn/gcn.c30
-rw-r--r--gcc/config/gcn/gcn.h11
2 files changed, 37 insertions, 4 deletions
diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index 54a1c0b..aa9d455 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -3610,6 +3610,34 @@ gcn_init_builtins (void)
#endif
}
+/* Implement TARGET_INIT_LIBFUNCS. */
+
+static void
+gcn_init_libfuncs (void)
+{
+ /* BITS_PER_UNIT * 2 is 64 bits, which causes
+ optabs-libfuncs.c:gen_int_libfunc to omit TImode (i.e 128 bits)
+ libcalls that we need to support operations for that type. Initialise
+ them here instead. */
+ set_optab_libfunc (udiv_optab, TImode, "__udivti3");
+ set_optab_libfunc (umod_optab, TImode, "__umodti3");
+ set_optab_libfunc (sdiv_optab, TImode, "__divti3");
+ set_optab_libfunc (smod_optab, TImode, "__modti3");
+ set_optab_libfunc (smul_optab, TImode, "__multi3");
+ set_optab_libfunc (addv_optab, TImode, "__addvti3");
+ set_optab_libfunc (subv_optab, TImode, "__subvti3");
+ set_optab_libfunc (negv_optab, TImode, "__negvti2");
+ set_optab_libfunc (absv_optab, TImode, "__absvti2");
+ set_optab_libfunc (smulv_optab, TImode, "__mulvti3");
+ set_optab_libfunc (ffs_optab, TImode, "__ffsti2");
+ set_optab_libfunc (clz_optab, TImode, "__clzti2");
+ set_optab_libfunc (ctz_optab, TImode, "__ctzti2");
+ set_optab_libfunc (clrsb_optab, TImode, "__clrsbti2");
+ set_optab_libfunc (popcount_optab, TImode, "__popcountti2");
+ set_optab_libfunc (parity_optab, TImode, "__parityti2");
+ set_optab_libfunc (bswap_optab, TImode, "__bswapti2");
+}
+
/* Expand the CMP_SWAP GCN builtins. We have our own versions that do
not require taking the address of any object, other than the memory
cell being operated on.
@@ -6345,6 +6373,8 @@ gcn_dwarf_register_span (rtx rtl)
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS gcn_init_builtins
+#undef TARGET_INIT_LIBFUNCS
+#define TARGET_INIT_LIBFUNCS gcn_init_libfuncs
#undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS
#define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS \
gcn_ira_change_pseudo_allocno_class
diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index eba4646..540835b 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -46,9 +46,12 @@
#define BYTES_BIG_ENDIAN 0
#define WORDS_BIG_ENDIAN 0
-#define BITS_PER_WORD 32
-#define UNITS_PER_WORD (BITS_PER_WORD/BITS_PER_UNIT)
-#define LIBGCC2_UNITS_PER_WORD 4
+#ifdef IN_LIBGCC2
+/* We want DImode and TImode helpers. */
+#define UNITS_PER_WORD 8
+#else
+#define UNITS_PER_WORD 4
+#endif
#define POINTER_SIZE 64
#define PARM_BOUNDARY 64
@@ -56,7 +59,7 @@
#define FUNCTION_BOUNDARY 32
#define BIGGEST_ALIGNMENT 64
#define EMPTY_FIELD_BOUNDARY 32
-#define MAX_FIXED_MODE_SIZE 64
+#define MAX_FIXED_MODE_SIZE 128
#define MAX_REGS_PER_ADDRESS 2
#define STACK_SIZE_MODE DImode
#define Pmode DImode