public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2020-12-04 22:04 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2020-12-04 22:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9f81fa7c85cc10af9e2a87f617ad3ead281b26a9
commit 9f81fa7c85cc10af9e2a87f617ad3ead281b26a9
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 +++++++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++++++++++----
gcc/config/darwin-d.c | 26 ++++++++++++
gcc/config/dragonfly-d.c | 26 ++++++++++++
gcc/config/freebsd-d.c | 26 ++++++++++++
gcc/config/glibc-d.c | 26 ++++++++++++
gcc/config/i386/i386-d.c | 28 +++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 ++++++++++++++
gcc/config/netbsd-d.c | 26 ++++++++++++
gcc/config/pa/pa-d.c | 28 +++++++++++++
gcc/config/riscv/riscv-d.c | 46 +++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++
gcc/config/sol2-d.c | 26 ++++++++++++
gcc/config/sparc/sparc-d.c | 28 +++++++++++++
gcc/d/d-builtins.cc | 31 +++++++++++----
gcc/d/d-compiler.cc | 4 +-
gcc/d/d-frontend.cc | 2 +-
gcc/d/d-target.cc | 90 ++++++++++++++++++++++++++++++++++++++++++
gcc/d/d-target.def | 20 ++++++++++
gcc/d/d-target.h | 15 +++++++
gcc/d/d-tree.h | 2 +-
gcc/d/dmd/idgen.c | 1 +
gcc/d/dmd/target.h | 1 +
gcc/d/dmd/traits.c | 24 +++++++++++
gcc/doc/tm.texi | 14 +++++++
gcc/doc/tm.texi.in | 4 ++
29 files changed, 644 insertions(+), 20 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 69efd8df3d2..b01367a33ec 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index e6c751c1e6c..138463e561b 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index ced07ce006a..7b8c72efe27 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 70ec820b75d..dac561e21d7 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index d79d82b5aa4..d8cf0dbab83 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 7eb9e315f00..ca5bcc52dac 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 56fec11846e..9e40c2c2c66 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65347a59b79..91bb77c6a4c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b8ae16e2865..4d249a211c9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -798,8 +798,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index a9d4ba1f0b3..cd4f97a81d3 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index 7c30d02b556..c7708edebff 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index dda555858e3..b792985a623 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 0fb08b49a30..34e7bc590a8 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index fd16e80aafd..d503a838c21 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 5a70e066e00..375c06a632a 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 27068f83082..dc542b4d5ee 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 53163c6f32e..f28693ff652 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 72e2d3a7168..b599931ae52 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -332,11 +332,12 @@ build_frontend_type (tree type)
}
/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
+ LOC is the location in the source file where this CST is being evaluated.
This is used for getting the CTFE value out of a const-folded builtin,
returns NULL if it cannot convert CST. */
Expression *
-d_eval_constant_expression (tree cst)
+d_eval_constant_expression (const Loc &loc, tree cst)
{
STRIP_TYPE_NOPS (cst);
Type *type = build_frontend_type (TREE_TYPE (cst));
@@ -353,23 +354,23 @@ d_eval_constant_expression (tree cst)
real_value re = TREE_REAL_CST (TREE_REALPART (cst));
real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
complex_t value = complex_t (ldouble (re), ldouble (im));
- return ComplexExp::create (Loc (), value, type);
+ return ComplexExp::create (loc, value, type);
}
else if (code == INTEGER_CST)
{
dinteger_t value = TREE_INT_CST_LOW (cst);
- return IntegerExp::create (Loc (), value, type);
+ return IntegerExp::create (loc, value, type);
}
else if (code == REAL_CST)
{
real_value value = TREE_REAL_CST (cst);
- return RealExp::create (Loc (), ldouble (value), type);
+ return RealExp::create (loc, ldouble (value), type);
}
else if (code == STRING_CST)
{
const void *string = TREE_STRING_POINTER (cst);
size_t len = TREE_STRING_LENGTH (cst);
- return StringExp::create (Loc (), CONST_CAST (void *, string), len);
+ return StringExp::create (loc, CONST_CAST (void *, string), len);
}
else if (code == VECTOR_CST)
{
@@ -380,17 +381,31 @@ d_eval_constant_expression (tree cst)
for (size_t i = 0; i < nunits; i++)
{
Expression *elem
- = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
+ = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
if (elem == NULL)
return NULL;
(*elements)[i] = elem;
}
- Expression *e = ArrayLiteralExp::create (Loc (), elements);
+ Expression *e = ArrayLiteralExp::create (loc, elements);
e->type = type->isTypeVector ()->basetype;
- return VectorExp::create (Loc (), e, type);
+ return VectorExp::create (loc, e, type);
+ }
+ else if (code == ADDR_EXPR)
+ {
+ /* Special handling for trees constructed by build_string_literal.
+ What we receive is an `&"string"[0]' expression, strip off the
+ outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
+ tree pointee = TREE_OPERAND (cst, 0);
+
+ if (TREE_CODE (pointee) != ARRAY_REF
+ || TREE_OPERAND (pointee, 1) != integer_zero_node
+ || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
+ return NULL;
+
+ return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
}
}
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index ffa7f78c82e..f737d8d9686 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -133,7 +133,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
cst = native_interpret_expr (vectype, buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL && e->op == TOKvector);
return e->isVectorExp ()->e1;
@@ -143,7 +143,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
/* Normal interpret cast. */
cst = native_interpret_expr (build_ctype (type), buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL);
return e;
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index da34e902275..91335307150 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -195,7 +195,7 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
/* Builtin should be successfully evaluated.
Will only return NULL if we can't convert it. */
if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
- e = d_eval_constant_expression (result);
+ e = d_eval_constant_expression (loc, result);
return e;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index cd136524eb9..5424ad0ae28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -44,6 +44,25 @@ along with GCC; see the file COPYING3. If not see
Target target;
+/* Table `__traits(getTargetInfo)' keys. */
+static vec<d_target_info_spec> target_info_table;
+
+/* Internal key handlers for `__traits(getTargetInfo)'. */
+static tree d_handle_target_cpp_std (void);
+static tree d_handle_target_cpp_runtime_library (void);
+
+/* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
+ which are always available. */
+static const struct d_target_info_spec d_language_target_info[] =
+{
+ /* { name, handler } */
+ { "cppStd", d_handle_target_cpp_std },
+ { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
+ { "floatAbi", NULL },
+ { "objectFormat", NULL },
+ { NULL, NULL },
+};
+
/* Initialize the floating-point constants for TYPE. */
@@ -167,6 +186,12 @@ Target::_init (const Param &)
real_convert (&CTFloat::one.rv (), mode, &dconst1);
real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
+
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
+ d_add_target_info_handlers (d_language_target_info);
}
/* Return GCC memory alignment size for type TYPE. */
@@ -413,3 +438,68 @@ Target::toArgTypes (Type *)
/* Not implemented, however this is not currently used anywhere. */
return NULL;
}
+
+
+/* Add all target info in HANDLERS to TARGET_INFO_TABLE for use by
+ Target::getTargetInfo(). */
+
+void
+d_add_target_info_handlers (const d_target_info_spec *handlers)
+{
+ gcc_assert (handlers != NULL);
+
+ if (target_info_table.is_empty ())
+ target_info_table.create (8);
+
+ for (size_t i = 0; handlers[i].name != NULL; i++)
+ target_info_table.safe_push (handlers[i]);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
+
+tree
+d_handle_target_cpp_std (void)
+{
+ return build_integer_cst (global.params.cplusplus);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
+
+tree
+d_handle_target_cpp_runtime_library (void)
+{
+ /* The driver only ever optionally links to libstdc++. */
+ const char *libstdcxx = "libstdc++";
+ return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
+}
+
+/* Look up the target info KEY in the available getTargetInfo tables, and return
+ the result as an Expression, or NULL if KEY is not found. When the key must
+ always exist, but is not supported, an empty string expression is returned.
+ LOC is the location to use for the returned expression. */
+
+Expression *
+Target::getTargetInfo (const char *key, const Loc &loc)
+{
+ unsigned ix;
+ d_target_info_spec *spec;
+
+ FOR_EACH_VEC_ELT (target_info_table, ix, spec)
+ {
+ tree result;
+
+ if (strcmp (key, spec->name) != 0)
+ continue;
+
+ /* Get the requested information, or empty string if unhandled. */
+ if (spec->handler)
+ result = (spec->handler) ();
+ else
+ result = build_string_literal (1, "");
+
+ gcc_assert (result);
+ return d_eval_constant_expression (loc, result);
+ }
+
+ return NULL;
+}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 728cba70335..4471d5155cc 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index d4413e47c61..8d3d6545a1c 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -31,4 +31,19 @@ extern struct gcc_targetdm targetdm;
/* Used by target to add predefined version idenditiers. */
extern void d_add_builtin_version (const char *);
+/* Structure describing a supported key for `__traits(getTargetInfo)' and a
+ function to handle it. */
+struct d_target_info_spec
+{
+ /* The name of the key or NULL to mark the end of a table of keys. */
+ const char *name;
+ /* Function to handle this key, the return value of the handler must be a CST.
+ This pointer may be NULL if no special handling is required, for instance,
+ the key must always be available according to the D language spec. */
+ tree (*handler) ();
+};
+
+/* Used by target to add getTargetInfo handlers. */
+extern void d_add_target_info_handlers (const d_target_info_spec *);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 31fe5181912..f5cf9d3f214 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -496,7 +496,7 @@ extern void d_init_builtins (void);
extern void d_register_builtin_type (tree, const char *);
extern void d_build_builtins_module (Module *);
extern void d_maybe_set_builtin (Module *);
-extern Expression *d_eval_constant_expression (tree);
+extern Expression *d_eval_constant_expression (const Loc &, tree);
extern void d_init_versions (void);
/* In d-codegen.cc. */
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index 16f3b5f29ec..316c5e3b0dd 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -360,6 +360,7 @@ Msgtable msgtable[] =
{ "getUnitTests", NULL },
{ "getVirtualIndex", NULL },
{ "getPointerBitmap", NULL },
+ { "getTargetInfo", NULL },
// For C++ mangling
{ "allocator", NULL },
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f2a55d6a134..20b505220e7 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -105,6 +105,7 @@ public:
// ABI and backend.
LINK systemLinkage();
TypeTuple *toArgTypes(Type *t);
+ Expression *getTargetInfo(const char* name, const Loc& loc);
};
extern Target target;
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index bc1e2c3c234..f859749be14 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -265,6 +266,7 @@ TraitsInitializer::TraitsInitializer()
"getUnitTests",
"getVirtualIndex",
"getPointerBitmap",
+ "getTargetInfo",
NULL
};
@@ -1471,6 +1473,28 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
return pointerBitmap(e);
}
+ else if (e->ident == Id::getTargetInfo)
+ {
+ if (dim != 1)
+ return dimError(e, 1, dim);
+
+ Expression *ex = isExpression((*e->args)[0]);
+ StringExp *se = ex ? ex->ctfeInterpret()->toStringExp() : NULL;
+ if (!ex || !se || se->len == 0)
+ {
+ e->error("string expected as argument of __traits `%s` instead of `%s`", e->ident->toChars(), ex->toChars());
+ return new ErrorExp();
+ }
+ se = se->toUTF8(sc);
+
+ Expression *r = target.getTargetInfo(se->toPtr(), e->loc);
+ if (!r)
+ {
+ e->error("`getTargetInfo` key `\"%s\"` not supported by this implementation", se->toPtr());
+ return new ErrorExp();
+ }
+ return semantic(r, sc);
+ }
if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f5077655716..0a7fb9eb542 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10835,6 +10835,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ad568581fd4..a14ae7780a5 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2020-12-04 23:08 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2020-12-04 23:08 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:aed534f40412bc708e04dbd435e88c469ee77bfa
commit aed534f40412bc708e04dbd435e88c469ee77bfa
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 +++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++---
gcc/config/darwin-d.c | 26 ++++++++
gcc/config/dragonfly-d.c | 26 ++++++++
gcc/config/freebsd-d.c | 26 ++++++++
gcc/config/glibc-d.c | 26 ++++++++
gcc/config/i386/i386-d.c | 28 +++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 +++++++++
gcc/config/netbsd-d.c | 26 ++++++++
gcc/config/pa/pa-d.c | 28 +++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 +++++++++
gcc/config/s390/s390-d.c | 30 +++++++++
gcc/config/sol2-d.c | 26 ++++++++
gcc/config/sparc/sparc-d.c | 28 +++++++++
gcc/d/d-builtins.cc | 31 ++++++---
gcc/d/d-compiler.cc | 4 +-
gcc/d/d-frontend.cc | 2 +-
gcc/d/d-target.cc | 90 +++++++++++++++++++++++++++
gcc/d/d-target.def | 20 ++++++
gcc/d/d-target.h | 15 +++++
gcc/d/d-tree.h | 2 +-
gcc/d/dmd/idgen.c | 1 +
gcc/d/dmd/target.h | 1 +
gcc/d/dmd/traits.c | 24 +++++++
gcc/doc/tm.texi | 14 +++++
gcc/doc/tm.texi.in | 4 ++
libphobos/libdruntime/core/sys/posix/setjmp.d | 3 +-
30 files changed, 646 insertions(+), 21 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 69efd8df3d2..b01367a33ec 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index e6c751c1e6c..138463e561b 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index ced07ce006a..7b8c72efe27 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 70ec820b75d..dac561e21d7 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index d79d82b5aa4..d8cf0dbab83 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 7eb9e315f00..ca5bcc52dac 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 56fec11846e..9e40c2c2c66 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65347a59b79..91bb77c6a4c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index b8ae16e2865..4d249a211c9 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -798,8 +798,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index a9d4ba1f0b3..cd4f97a81d3 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index 7c30d02b556..c7708edebff 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index dda555858e3..b792985a623 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 0fb08b49a30..34e7bc590a8 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index fd16e80aafd..d503a838c21 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 5a70e066e00..375c06a632a 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 27068f83082..dc542b4d5ee 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 53163c6f32e..f28693ff652 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 72e2d3a7168..b599931ae52 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -332,11 +332,12 @@ build_frontend_type (tree type)
}
/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
+ LOC is the location in the source file where this CST is being evaluated.
This is used for getting the CTFE value out of a const-folded builtin,
returns NULL if it cannot convert CST. */
Expression *
-d_eval_constant_expression (tree cst)
+d_eval_constant_expression (const Loc &loc, tree cst)
{
STRIP_TYPE_NOPS (cst);
Type *type = build_frontend_type (TREE_TYPE (cst));
@@ -353,23 +354,23 @@ d_eval_constant_expression (tree cst)
real_value re = TREE_REAL_CST (TREE_REALPART (cst));
real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
complex_t value = complex_t (ldouble (re), ldouble (im));
- return ComplexExp::create (Loc (), value, type);
+ return ComplexExp::create (loc, value, type);
}
else if (code == INTEGER_CST)
{
dinteger_t value = TREE_INT_CST_LOW (cst);
- return IntegerExp::create (Loc (), value, type);
+ return IntegerExp::create (loc, value, type);
}
else if (code == REAL_CST)
{
real_value value = TREE_REAL_CST (cst);
- return RealExp::create (Loc (), ldouble (value), type);
+ return RealExp::create (loc, ldouble (value), type);
}
else if (code == STRING_CST)
{
const void *string = TREE_STRING_POINTER (cst);
size_t len = TREE_STRING_LENGTH (cst);
- return StringExp::create (Loc (), CONST_CAST (void *, string), len);
+ return StringExp::create (loc, CONST_CAST (void *, string), len);
}
else if (code == VECTOR_CST)
{
@@ -380,17 +381,31 @@ d_eval_constant_expression (tree cst)
for (size_t i = 0; i < nunits; i++)
{
Expression *elem
- = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
+ = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
if (elem == NULL)
return NULL;
(*elements)[i] = elem;
}
- Expression *e = ArrayLiteralExp::create (Loc (), elements);
+ Expression *e = ArrayLiteralExp::create (loc, elements);
e->type = type->isTypeVector ()->basetype;
- return VectorExp::create (Loc (), e, type);
+ return VectorExp::create (loc, e, type);
+ }
+ else if (code == ADDR_EXPR)
+ {
+ /* Special handling for trees constructed by build_string_literal.
+ What we receive is an `&"string"[0]' expression, strip off the
+ outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
+ tree pointee = TREE_OPERAND (cst, 0);
+
+ if (TREE_CODE (pointee) != ARRAY_REF
+ || TREE_OPERAND (pointee, 1) != integer_zero_node
+ || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
+ return NULL;
+
+ return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
}
}
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index ffa7f78c82e..f737d8d9686 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -133,7 +133,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
cst = native_interpret_expr (vectype, buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL && e->op == TOKvector);
return e->isVectorExp ()->e1;
@@ -143,7 +143,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
/* Normal interpret cast. */
cst = native_interpret_expr (build_ctype (type), buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL);
return e;
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index da34e902275..91335307150 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -195,7 +195,7 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
/* Builtin should be successfully evaluated.
Will only return NULL if we can't convert it. */
if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
- e = d_eval_constant_expression (result);
+ e = d_eval_constant_expression (loc, result);
return e;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index cd136524eb9..5424ad0ae28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -44,6 +44,25 @@ along with GCC; see the file COPYING3. If not see
Target target;
+/* Table `__traits(getTargetInfo)' keys. */
+static vec<d_target_info_spec> target_info_table;
+
+/* Internal key handlers for `__traits(getTargetInfo)'. */
+static tree d_handle_target_cpp_std (void);
+static tree d_handle_target_cpp_runtime_library (void);
+
+/* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
+ which are always available. */
+static const struct d_target_info_spec d_language_target_info[] =
+{
+ /* { name, handler } */
+ { "cppStd", d_handle_target_cpp_std },
+ { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
+ { "floatAbi", NULL },
+ { "objectFormat", NULL },
+ { NULL, NULL },
+};
+
/* Initialize the floating-point constants for TYPE. */
@@ -167,6 +186,12 @@ Target::_init (const Param &)
real_convert (&CTFloat::one.rv (), mode, &dconst1);
real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
+
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
+ d_add_target_info_handlers (d_language_target_info);
}
/* Return GCC memory alignment size for type TYPE. */
@@ -413,3 +438,68 @@ Target::toArgTypes (Type *)
/* Not implemented, however this is not currently used anywhere. */
return NULL;
}
+
+
+/* Add all target info in HANDLERS to TARGET_INFO_TABLE for use by
+ Target::getTargetInfo(). */
+
+void
+d_add_target_info_handlers (const d_target_info_spec *handlers)
+{
+ gcc_assert (handlers != NULL);
+
+ if (target_info_table.is_empty ())
+ target_info_table.create (8);
+
+ for (size_t i = 0; handlers[i].name != NULL; i++)
+ target_info_table.safe_push (handlers[i]);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
+
+tree
+d_handle_target_cpp_std (void)
+{
+ return build_integer_cst (global.params.cplusplus);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
+
+tree
+d_handle_target_cpp_runtime_library (void)
+{
+ /* The driver only ever optionally links to libstdc++. */
+ const char *libstdcxx = "libstdc++";
+ return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
+}
+
+/* Look up the target info KEY in the available getTargetInfo tables, and return
+ the result as an Expression, or NULL if KEY is not found. When the key must
+ always exist, but is not supported, an empty string expression is returned.
+ LOC is the location to use for the returned expression. */
+
+Expression *
+Target::getTargetInfo (const char *key, const Loc &loc)
+{
+ unsigned ix;
+ d_target_info_spec *spec;
+
+ FOR_EACH_VEC_ELT (target_info_table, ix, spec)
+ {
+ tree result;
+
+ if (strcmp (key, spec->name) != 0)
+ continue;
+
+ /* Get the requested information, or empty string if unhandled. */
+ if (spec->handler)
+ result = (spec->handler) ();
+ else
+ result = build_string_literal (1, "");
+
+ gcc_assert (result);
+ return d_eval_constant_expression (loc, result);
+ }
+
+ return NULL;
+}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 728cba70335..4471d5155cc 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index d4413e47c61..8d3d6545a1c 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -31,4 +31,19 @@ extern struct gcc_targetdm targetdm;
/* Used by target to add predefined version idenditiers. */
extern void d_add_builtin_version (const char *);
+/* Structure describing a supported key for `__traits(getTargetInfo)' and a
+ function to handle it. */
+struct d_target_info_spec
+{
+ /* The name of the key or NULL to mark the end of a table of keys. */
+ const char *name;
+ /* Function to handle this key, the return value of the handler must be a CST.
+ This pointer may be NULL if no special handling is required, for instance,
+ the key must always be available according to the D language spec. */
+ tree (*handler) ();
+};
+
+/* Used by target to add getTargetInfo handlers. */
+extern void d_add_target_info_handlers (const d_target_info_spec *);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 31fe5181912..f5cf9d3f214 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -496,7 +496,7 @@ extern void d_init_builtins (void);
extern void d_register_builtin_type (tree, const char *);
extern void d_build_builtins_module (Module *);
extern void d_maybe_set_builtin (Module *);
-extern Expression *d_eval_constant_expression (tree);
+extern Expression *d_eval_constant_expression (const Loc &, tree);
extern void d_init_versions (void);
/* In d-codegen.cc. */
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index 16f3b5f29ec..316c5e3b0dd 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -360,6 +360,7 @@ Msgtable msgtable[] =
{ "getUnitTests", NULL },
{ "getVirtualIndex", NULL },
{ "getPointerBitmap", NULL },
+ { "getTargetInfo", NULL },
// For C++ mangling
{ "allocator", NULL },
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f2a55d6a134..20b505220e7 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -105,6 +105,7 @@ public:
// ABI and backend.
LINK systemLinkage();
TypeTuple *toArgTypes(Type *t);
+ Expression *getTargetInfo(const char* name, const Loc& loc);
};
extern Target target;
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index bc1e2c3c234..f859749be14 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -265,6 +266,7 @@ TraitsInitializer::TraitsInitializer()
"getUnitTests",
"getVirtualIndex",
"getPointerBitmap",
+ "getTargetInfo",
NULL
};
@@ -1471,6 +1473,28 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
return pointerBitmap(e);
}
+ else if (e->ident == Id::getTargetInfo)
+ {
+ if (dim != 1)
+ return dimError(e, 1, dim);
+
+ Expression *ex = isExpression((*e->args)[0]);
+ StringExp *se = ex ? ex->ctfeInterpret()->toStringExp() : NULL;
+ if (!ex || !se || se->len == 0)
+ {
+ e->error("string expected as argument of __traits `%s` instead of `%s`", e->ident->toChars(), ex->toChars());
+ return new ErrorExp();
+ }
+ se = se->toUTF8(sc);
+
+ Expression *r = target.getTargetInfo(se->toPtr(), e->loc);
+ if (!r)
+ {
+ e->error("`getTargetInfo` key `\"%s\"` not supported by this implementation", se->toPtr());
+ return new ErrorExp();
+ }
+ return semantic(r, sc);
+ }
if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f5077655716..0a7fb9eb542 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10835,6 +10835,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ad568581fd4..a14ae7780a5 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f7086f2..3f5cb2a8241 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -151,7 +151,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2020-12-05 23:47 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2020-12-05 23:47 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:65f94d9cd9b9897d27ec917b7fc06fe372163155
commit 65f94d9cd9b9897d27ec917b7fc06fe372163155
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 +++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++---
gcc/config/darwin-d.c | 26 ++++++++
gcc/config/dragonfly-d.c | 26 ++++++++
gcc/config/freebsd-d.c | 26 ++++++++
gcc/config/glibc-d.c | 26 ++++++++
gcc/config/i386/i386-d.c | 28 +++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 +++++++++
gcc/config/netbsd-d.c | 26 ++++++++
gcc/config/pa/pa-d.c | 28 +++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 +++++++++
gcc/config/s390/s390-d.c | 30 +++++++++
gcc/config/sol2-d.c | 26 ++++++++
gcc/config/sparc/sparc-d.c | 28 +++++++++
gcc/d/d-builtins.cc | 31 ++++++---
gcc/d/d-compiler.cc | 4 +-
gcc/d/d-frontend.cc | 2 +-
gcc/d/d-target.cc | 90 +++++++++++++++++++++++++++
gcc/d/d-target.def | 20 ++++++
gcc/d/d-target.h | 15 +++++
gcc/d/d-tree.h | 2 +-
gcc/d/dmd/idgen.c | 1 +
gcc/d/dmd/target.h | 1 +
gcc/d/dmd/traits.c | 24 +++++++
gcc/doc/tm.texi | 14 +++++
gcc/doc/tm.texi.in | 4 ++
libphobos/libdruntime/core/sys/posix/setjmp.d | 3 +-
30 files changed, 646 insertions(+), 21 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 69efd8df3d2..b01367a33ec 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index e6c751c1e6c..138463e561b 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index ced07ce006a..7b8c72efe27 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 70ec820b75d..dac561e21d7 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index d79d82b5aa4..d8cf0dbab83 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 7eb9e315f00..ca5bcc52dac 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 56fec11846e..9e40c2c2c66 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65347a59b79..91bb77c6a4c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 5680fdca905..9e7bde23441 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index a9d4ba1f0b3..cd4f97a81d3 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index 7c30d02b556..c7708edebff 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index dda555858e3..b792985a623 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 0fb08b49a30..34e7bc590a8 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index fd16e80aafd..d503a838c21 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 5a70e066e00..375c06a632a 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 27068f83082..dc542b4d5ee 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 53163c6f32e..f28693ff652 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 72e2d3a7168..b599931ae52 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -332,11 +332,12 @@ build_frontend_type (tree type)
}
/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
+ LOC is the location in the source file where this CST is being evaluated.
This is used for getting the CTFE value out of a const-folded builtin,
returns NULL if it cannot convert CST. */
Expression *
-d_eval_constant_expression (tree cst)
+d_eval_constant_expression (const Loc &loc, tree cst)
{
STRIP_TYPE_NOPS (cst);
Type *type = build_frontend_type (TREE_TYPE (cst));
@@ -353,23 +354,23 @@ d_eval_constant_expression (tree cst)
real_value re = TREE_REAL_CST (TREE_REALPART (cst));
real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
complex_t value = complex_t (ldouble (re), ldouble (im));
- return ComplexExp::create (Loc (), value, type);
+ return ComplexExp::create (loc, value, type);
}
else if (code == INTEGER_CST)
{
dinteger_t value = TREE_INT_CST_LOW (cst);
- return IntegerExp::create (Loc (), value, type);
+ return IntegerExp::create (loc, value, type);
}
else if (code == REAL_CST)
{
real_value value = TREE_REAL_CST (cst);
- return RealExp::create (Loc (), ldouble (value), type);
+ return RealExp::create (loc, ldouble (value), type);
}
else if (code == STRING_CST)
{
const void *string = TREE_STRING_POINTER (cst);
size_t len = TREE_STRING_LENGTH (cst);
- return StringExp::create (Loc (), CONST_CAST (void *, string), len);
+ return StringExp::create (loc, CONST_CAST (void *, string), len);
}
else if (code == VECTOR_CST)
{
@@ -380,17 +381,31 @@ d_eval_constant_expression (tree cst)
for (size_t i = 0; i < nunits; i++)
{
Expression *elem
- = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
+ = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
if (elem == NULL)
return NULL;
(*elements)[i] = elem;
}
- Expression *e = ArrayLiteralExp::create (Loc (), elements);
+ Expression *e = ArrayLiteralExp::create (loc, elements);
e->type = type->isTypeVector ()->basetype;
- return VectorExp::create (Loc (), e, type);
+ return VectorExp::create (loc, e, type);
+ }
+ else if (code == ADDR_EXPR)
+ {
+ /* Special handling for trees constructed by build_string_literal.
+ What we receive is an `&"string"[0]' expression, strip off the
+ outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
+ tree pointee = TREE_OPERAND (cst, 0);
+
+ if (TREE_CODE (pointee) != ARRAY_REF
+ || TREE_OPERAND (pointee, 1) != integer_zero_node
+ || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
+ return NULL;
+
+ return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
}
}
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index ffa7f78c82e..f737d8d9686 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -133,7 +133,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
cst = native_interpret_expr (vectype, buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL && e->op == TOKvector);
return e->isVectorExp ()->e1;
@@ -143,7 +143,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
/* Normal interpret cast. */
cst = native_interpret_expr (build_ctype (type), buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL);
return e;
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index da34e902275..91335307150 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -195,7 +195,7 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
/* Builtin should be successfully evaluated.
Will only return NULL if we can't convert it. */
if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
- e = d_eval_constant_expression (result);
+ e = d_eval_constant_expression (loc, result);
return e;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index cd136524eb9..5424ad0ae28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -44,6 +44,25 @@ along with GCC; see the file COPYING3. If not see
Target target;
+/* Table `__traits(getTargetInfo)' keys. */
+static vec<d_target_info_spec> target_info_table;
+
+/* Internal key handlers for `__traits(getTargetInfo)'. */
+static tree d_handle_target_cpp_std (void);
+static tree d_handle_target_cpp_runtime_library (void);
+
+/* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
+ which are always available. */
+static const struct d_target_info_spec d_language_target_info[] =
+{
+ /* { name, handler } */
+ { "cppStd", d_handle_target_cpp_std },
+ { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
+ { "floatAbi", NULL },
+ { "objectFormat", NULL },
+ { NULL, NULL },
+};
+
/* Initialize the floating-point constants for TYPE. */
@@ -167,6 +186,12 @@ Target::_init (const Param &)
real_convert (&CTFloat::one.rv (), mode, &dconst1);
real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
+
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
+ d_add_target_info_handlers (d_language_target_info);
}
/* Return GCC memory alignment size for type TYPE. */
@@ -413,3 +438,68 @@ Target::toArgTypes (Type *)
/* Not implemented, however this is not currently used anywhere. */
return NULL;
}
+
+
+/* Add all target info in HANDLERS to TARGET_INFO_TABLE for use by
+ Target::getTargetInfo(). */
+
+void
+d_add_target_info_handlers (const d_target_info_spec *handlers)
+{
+ gcc_assert (handlers != NULL);
+
+ if (target_info_table.is_empty ())
+ target_info_table.create (8);
+
+ for (size_t i = 0; handlers[i].name != NULL; i++)
+ target_info_table.safe_push (handlers[i]);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
+
+tree
+d_handle_target_cpp_std (void)
+{
+ return build_integer_cst (global.params.cplusplus);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
+
+tree
+d_handle_target_cpp_runtime_library (void)
+{
+ /* The driver only ever optionally links to libstdc++. */
+ const char *libstdcxx = "libstdc++";
+ return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
+}
+
+/* Look up the target info KEY in the available getTargetInfo tables, and return
+ the result as an Expression, or NULL if KEY is not found. When the key must
+ always exist, but is not supported, an empty string expression is returned.
+ LOC is the location to use for the returned expression. */
+
+Expression *
+Target::getTargetInfo (const char *key, const Loc &loc)
+{
+ unsigned ix;
+ d_target_info_spec *spec;
+
+ FOR_EACH_VEC_ELT (target_info_table, ix, spec)
+ {
+ tree result;
+
+ if (strcmp (key, spec->name) != 0)
+ continue;
+
+ /* Get the requested information, or empty string if unhandled. */
+ if (spec->handler)
+ result = (spec->handler) ();
+ else
+ result = build_string_literal (1, "");
+
+ gcc_assert (result);
+ return d_eval_constant_expression (loc, result);
+ }
+
+ return NULL;
+}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 728cba70335..4471d5155cc 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index d4413e47c61..8d3d6545a1c 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -31,4 +31,19 @@ extern struct gcc_targetdm targetdm;
/* Used by target to add predefined version idenditiers. */
extern void d_add_builtin_version (const char *);
+/* Structure describing a supported key for `__traits(getTargetInfo)' and a
+ function to handle it. */
+struct d_target_info_spec
+{
+ /* The name of the key or NULL to mark the end of a table of keys. */
+ const char *name;
+ /* Function to handle this key, the return value of the handler must be a CST.
+ This pointer may be NULL if no special handling is required, for instance,
+ the key must always be available according to the D language spec. */
+ tree (*handler) ();
+};
+
+/* Used by target to add getTargetInfo handlers. */
+extern void d_add_target_info_handlers (const d_target_info_spec *);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 31fe5181912..f5cf9d3f214 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -496,7 +496,7 @@ extern void d_init_builtins (void);
extern void d_register_builtin_type (tree, const char *);
extern void d_build_builtins_module (Module *);
extern void d_maybe_set_builtin (Module *);
-extern Expression *d_eval_constant_expression (tree);
+extern Expression *d_eval_constant_expression (const Loc &, tree);
extern void d_init_versions (void);
/* In d-codegen.cc. */
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index 16f3b5f29ec..316c5e3b0dd 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -360,6 +360,7 @@ Msgtable msgtable[] =
{ "getUnitTests", NULL },
{ "getVirtualIndex", NULL },
{ "getPointerBitmap", NULL },
+ { "getTargetInfo", NULL },
// For C++ mangling
{ "allocator", NULL },
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f2a55d6a134..20b505220e7 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -105,6 +105,7 @@ public:
// ABI and backend.
LINK systemLinkage();
TypeTuple *toArgTypes(Type *t);
+ Expression *getTargetInfo(const char* name, const Loc& loc);
};
extern Target target;
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index bc1e2c3c234..f859749be14 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -265,6 +266,7 @@ TraitsInitializer::TraitsInitializer()
"getUnitTests",
"getVirtualIndex",
"getPointerBitmap",
+ "getTargetInfo",
NULL
};
@@ -1471,6 +1473,28 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
return pointerBitmap(e);
}
+ else if (e->ident == Id::getTargetInfo)
+ {
+ if (dim != 1)
+ return dimError(e, 1, dim);
+
+ Expression *ex = isExpression((*e->args)[0]);
+ StringExp *se = ex ? ex->ctfeInterpret()->toStringExp() : NULL;
+ if (!ex || !se || se->len == 0)
+ {
+ e->error("string expected as argument of __traits `%s` instead of `%s`", e->ident->toChars(), ex->toChars());
+ return new ErrorExp();
+ }
+ se = se->toUTF8(sc);
+
+ Expression *r = target.getTargetInfo(se->toPtr(), e->loc);
+ if (!r)
+ {
+ e->error("`getTargetInfo` key `\"%s\"` not supported by this implementation", se->toPtr());
+ return new ErrorExp();
+ }
+ return semantic(r, sc);
+ }
if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d9b855c13ac..8e8475dfdd9 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10801,6 +10801,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ad568581fd4..a14ae7780a5 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f7086f2..3f5cb2a8241 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -151,7 +151,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2020-12-09 9:51 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2020-12-09 9:51 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7518645e673973d2d164a5c7f0f6a7f7d0ed3267
commit 7518645e673973d2d164a5c7f0f6a7f7d0ed3267
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 +++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++---
gcc/config/darwin-d.c | 26 ++++++++
gcc/config/dragonfly-d.c | 26 ++++++++
gcc/config/freebsd-d.c | 26 ++++++++
gcc/config/glibc-d.c | 26 ++++++++
gcc/config/i386/i386-d.c | 28 +++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 +++++++++
gcc/config/netbsd-d.c | 26 ++++++++
gcc/config/pa/pa-d.c | 28 +++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 +++++++++
gcc/config/s390/s390-d.c | 30 +++++++++
gcc/config/sol2-d.c | 26 ++++++++
gcc/config/sparc/sparc-d.c | 28 +++++++++
gcc/d/d-builtins.cc | 31 ++++++---
gcc/d/d-compiler.cc | 4 +-
gcc/d/d-frontend.cc | 2 +-
gcc/d/d-target.cc | 90 +++++++++++++++++++++++++++
gcc/d/d-target.def | 20 ++++++
gcc/d/d-target.h | 15 +++++
gcc/d/d-tree.h | 2 +-
gcc/d/dmd/idgen.c | 1 +
gcc/d/dmd/target.h | 1 +
gcc/d/dmd/traits.c | 24 +++++++
gcc/doc/tm.texi | 14 +++++
gcc/doc/tm.texi.in | 4 ++
libphobos/libdruntime/core/sys/posix/setjmp.d | 3 +-
30 files changed, 646 insertions(+), 21 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 69efd8df3d2..b01367a33ec 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index e6c751c1e6c..138463e561b 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index ced07ce006a..7b8c72efe27 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 70ec820b75d..dac561e21d7 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index d79d82b5aa4..d8cf0dbab83 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 7eb9e315f00..ca5bcc52dac 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 56fec11846e..9e40c2c2c66 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65347a59b79..91bb77c6a4c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d157d30ec17..aa5dcae983e 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index a9d4ba1f0b3..cd4f97a81d3 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index 7c30d02b556..c7708edebff 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index dda555858e3..b792985a623 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 0fb08b49a30..34e7bc590a8 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index fd16e80aafd..d503a838c21 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 5a70e066e00..375c06a632a 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 27068f83082..dc542b4d5ee 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 53163c6f32e..f28693ff652 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 72e2d3a7168..b599931ae52 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -332,11 +332,12 @@ build_frontend_type (tree type)
}
/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
+ LOC is the location in the source file where this CST is being evaluated.
This is used for getting the CTFE value out of a const-folded builtin,
returns NULL if it cannot convert CST. */
Expression *
-d_eval_constant_expression (tree cst)
+d_eval_constant_expression (const Loc &loc, tree cst)
{
STRIP_TYPE_NOPS (cst);
Type *type = build_frontend_type (TREE_TYPE (cst));
@@ -353,23 +354,23 @@ d_eval_constant_expression (tree cst)
real_value re = TREE_REAL_CST (TREE_REALPART (cst));
real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
complex_t value = complex_t (ldouble (re), ldouble (im));
- return ComplexExp::create (Loc (), value, type);
+ return ComplexExp::create (loc, value, type);
}
else if (code == INTEGER_CST)
{
dinteger_t value = TREE_INT_CST_LOW (cst);
- return IntegerExp::create (Loc (), value, type);
+ return IntegerExp::create (loc, value, type);
}
else if (code == REAL_CST)
{
real_value value = TREE_REAL_CST (cst);
- return RealExp::create (Loc (), ldouble (value), type);
+ return RealExp::create (loc, ldouble (value), type);
}
else if (code == STRING_CST)
{
const void *string = TREE_STRING_POINTER (cst);
size_t len = TREE_STRING_LENGTH (cst);
- return StringExp::create (Loc (), CONST_CAST (void *, string), len);
+ return StringExp::create (loc, CONST_CAST (void *, string), len);
}
else if (code == VECTOR_CST)
{
@@ -380,17 +381,31 @@ d_eval_constant_expression (tree cst)
for (size_t i = 0; i < nunits; i++)
{
Expression *elem
- = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
+ = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
if (elem == NULL)
return NULL;
(*elements)[i] = elem;
}
- Expression *e = ArrayLiteralExp::create (Loc (), elements);
+ Expression *e = ArrayLiteralExp::create (loc, elements);
e->type = type->isTypeVector ()->basetype;
- return VectorExp::create (Loc (), e, type);
+ return VectorExp::create (loc, e, type);
+ }
+ else if (code == ADDR_EXPR)
+ {
+ /* Special handling for trees constructed by build_string_literal.
+ What we receive is an `&"string"[0]' expression, strip off the
+ outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
+ tree pointee = TREE_OPERAND (cst, 0);
+
+ if (TREE_CODE (pointee) != ARRAY_REF
+ || TREE_OPERAND (pointee, 1) != integer_zero_node
+ || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
+ return NULL;
+
+ return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
}
}
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index ffa7f78c82e..f737d8d9686 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -133,7 +133,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
cst = native_interpret_expr (vectype, buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL && e->op == TOKvector);
return e->isVectorExp ()->e1;
@@ -143,7 +143,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
/* Normal interpret cast. */
cst = native_interpret_expr (build_ctype (type), buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL);
return e;
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index da34e902275..91335307150 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -195,7 +195,7 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
/* Builtin should be successfully evaluated.
Will only return NULL if we can't convert it. */
if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
- e = d_eval_constant_expression (result);
+ e = d_eval_constant_expression (loc, result);
return e;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index cd136524eb9..5424ad0ae28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -44,6 +44,25 @@ along with GCC; see the file COPYING3. If not see
Target target;
+/* Table `__traits(getTargetInfo)' keys. */
+static vec<d_target_info_spec> target_info_table;
+
+/* Internal key handlers for `__traits(getTargetInfo)'. */
+static tree d_handle_target_cpp_std (void);
+static tree d_handle_target_cpp_runtime_library (void);
+
+/* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
+ which are always available. */
+static const struct d_target_info_spec d_language_target_info[] =
+{
+ /* { name, handler } */
+ { "cppStd", d_handle_target_cpp_std },
+ { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
+ { "floatAbi", NULL },
+ { "objectFormat", NULL },
+ { NULL, NULL },
+};
+
/* Initialize the floating-point constants for TYPE. */
@@ -167,6 +186,12 @@ Target::_init (const Param &)
real_convert (&CTFloat::one.rv (), mode, &dconst1);
real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
+
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
+ d_add_target_info_handlers (d_language_target_info);
}
/* Return GCC memory alignment size for type TYPE. */
@@ -413,3 +438,68 @@ Target::toArgTypes (Type *)
/* Not implemented, however this is not currently used anywhere. */
return NULL;
}
+
+
+/* Add all target info in HANDLERS to TARGET_INFO_TABLE for use by
+ Target::getTargetInfo(). */
+
+void
+d_add_target_info_handlers (const d_target_info_spec *handlers)
+{
+ gcc_assert (handlers != NULL);
+
+ if (target_info_table.is_empty ())
+ target_info_table.create (8);
+
+ for (size_t i = 0; handlers[i].name != NULL; i++)
+ target_info_table.safe_push (handlers[i]);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
+
+tree
+d_handle_target_cpp_std (void)
+{
+ return build_integer_cst (global.params.cplusplus);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
+
+tree
+d_handle_target_cpp_runtime_library (void)
+{
+ /* The driver only ever optionally links to libstdc++. */
+ const char *libstdcxx = "libstdc++";
+ return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
+}
+
+/* Look up the target info KEY in the available getTargetInfo tables, and return
+ the result as an Expression, or NULL if KEY is not found. When the key must
+ always exist, but is not supported, an empty string expression is returned.
+ LOC is the location to use for the returned expression. */
+
+Expression *
+Target::getTargetInfo (const char *key, const Loc &loc)
+{
+ unsigned ix;
+ d_target_info_spec *spec;
+
+ FOR_EACH_VEC_ELT (target_info_table, ix, spec)
+ {
+ tree result;
+
+ if (strcmp (key, spec->name) != 0)
+ continue;
+
+ /* Get the requested information, or empty string if unhandled. */
+ if (spec->handler)
+ result = (spec->handler) ();
+ else
+ result = build_string_literal (1, "");
+
+ gcc_assert (result);
+ return d_eval_constant_expression (loc, result);
+ }
+
+ return NULL;
+}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 728cba70335..4471d5155cc 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index d4413e47c61..8d3d6545a1c 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -31,4 +31,19 @@ extern struct gcc_targetdm targetdm;
/* Used by target to add predefined version idenditiers. */
extern void d_add_builtin_version (const char *);
+/* Structure describing a supported key for `__traits(getTargetInfo)' and a
+ function to handle it. */
+struct d_target_info_spec
+{
+ /* The name of the key or NULL to mark the end of a table of keys. */
+ const char *name;
+ /* Function to handle this key, the return value of the handler must be a CST.
+ This pointer may be NULL if no special handling is required, for instance,
+ the key must always be available according to the D language spec. */
+ tree (*handler) ();
+};
+
+/* Used by target to add getTargetInfo handlers. */
+extern void d_add_target_info_handlers (const d_target_info_spec *);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 31fe5181912..f5cf9d3f214 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -496,7 +496,7 @@ extern void d_init_builtins (void);
extern void d_register_builtin_type (tree, const char *);
extern void d_build_builtins_module (Module *);
extern void d_maybe_set_builtin (Module *);
-extern Expression *d_eval_constant_expression (tree);
+extern Expression *d_eval_constant_expression (const Loc &, tree);
extern void d_init_versions (void);
/* In d-codegen.cc. */
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index 16f3b5f29ec..316c5e3b0dd 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -360,6 +360,7 @@ Msgtable msgtable[] =
{ "getUnitTests", NULL },
{ "getVirtualIndex", NULL },
{ "getPointerBitmap", NULL },
+ { "getTargetInfo", NULL },
// For C++ mangling
{ "allocator", NULL },
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f2a55d6a134..20b505220e7 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -105,6 +105,7 @@ public:
// ABI and backend.
LINK systemLinkage();
TypeTuple *toArgTypes(Type *t);
+ Expression *getTargetInfo(const char* name, const Loc& loc);
};
extern Target target;
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index bc1e2c3c234..f859749be14 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -265,6 +266,7 @@ TraitsInitializer::TraitsInitializer()
"getUnitTests",
"getVirtualIndex",
"getPointerBitmap",
+ "getTargetInfo",
NULL
};
@@ -1471,6 +1473,28 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
return pointerBitmap(e);
}
+ else if (e->ident == Id::getTargetInfo)
+ {
+ if (dim != 1)
+ return dimError(e, 1, dim);
+
+ Expression *ex = isExpression((*e->args)[0]);
+ StringExp *se = ex ? ex->ctfeInterpret()->toStringExp() : NULL;
+ if (!ex || !se || se->len == 0)
+ {
+ e->error("string expected as argument of __traits `%s` instead of `%s`", e->ident->toChars(), ex->toChars());
+ return new ErrorExp();
+ }
+ se = se->toUTF8(sc);
+
+ Expression *r = target.getTargetInfo(se->toPtr(), e->loc);
+ if (!r)
+ {
+ e->error("`getTargetInfo` key `\"%s\"` not supported by this implementation", se->toPtr());
+ return new ErrorExp();
+ }
+ return semantic(r, sc);
+ }
if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index d9b855c13ac..8e8475dfdd9 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10801,6 +10801,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ad568581fd4..a14ae7780a5 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f7086f2..3f5cb2a8241 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -151,7 +151,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2020-12-22 13:40 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2020-12-22 13:40 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:57ac0afbfb8a7789eed76daaf9d73c1983efbaee
commit 57ac0afbfb8a7789eed76daaf9d73c1983efbaee
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 +++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++---
gcc/config/darwin-d.c | 26 ++++++++
gcc/config/dragonfly-d.c | 26 ++++++++
gcc/config/freebsd-d.c | 26 ++++++++
gcc/config/glibc-d.c | 26 ++++++++
gcc/config/i386/i386-d.c | 28 +++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 +++++++++
gcc/config/netbsd-d.c | 26 ++++++++
gcc/config/pa/pa-d.c | 28 +++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 +++++++++
gcc/config/s390/s390-d.c | 30 +++++++++
gcc/config/sol2-d.c | 26 ++++++++
gcc/config/sparc/sparc-d.c | 28 +++++++++
gcc/d/d-builtins.cc | 31 ++++++---
gcc/d/d-compiler.cc | 4 +-
gcc/d/d-frontend.cc | 2 +-
gcc/d/d-target.cc | 90 +++++++++++++++++++++++++++
gcc/d/d-target.def | 20 ++++++
gcc/d/d-target.h | 15 +++++
gcc/d/d-tree.h | 2 +-
gcc/d/dmd/idgen.c | 1 +
gcc/d/dmd/target.h | 1 +
gcc/d/dmd/traits.c | 24 +++++++
gcc/doc/tm.texi | 14 +++++
gcc/doc/tm.texi.in | 4 ++
libphobos/libdruntime/core/sys/posix/setjmp.d | 3 +-
30 files changed, 646 insertions(+), 21 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 69efd8df3d2..b01367a33ec 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index e6c751c1e6c..138463e561b 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index ced07ce006a..7b8c72efe27 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 70ec820b75d..dac561e21d7 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index d79d82b5aa4..d8cf0dbab83 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 7eb9e315f00..ca5bcc52dac 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 56fec11846e..9e40c2c2c66 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 65347a59b79..91bb77c6a4c 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index e88738ca873..3965ba861b3 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index a9d4ba1f0b3..cd4f97a81d3 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index 7c30d02b556..c7708edebff 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index dda555858e3..b792985a623 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 0fb08b49a30..34e7bc590a8 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index fd16e80aafd..d503a838c21 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 5a70e066e00..375c06a632a 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 27068f83082..dc542b4d5ee 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 53163c6f32e..f28693ff652 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-builtins.cc b/gcc/d/d-builtins.cc
index 72e2d3a7168..b599931ae52 100644
--- a/gcc/d/d-builtins.cc
+++ b/gcc/d/d-builtins.cc
@@ -332,11 +332,12 @@ build_frontend_type (tree type)
}
/* Attempt to convert GCC evaluated CST to a D Frontend Expression.
+ LOC is the location in the source file where this CST is being evaluated.
This is used for getting the CTFE value out of a const-folded builtin,
returns NULL if it cannot convert CST. */
Expression *
-d_eval_constant_expression (tree cst)
+d_eval_constant_expression (const Loc &loc, tree cst)
{
STRIP_TYPE_NOPS (cst);
Type *type = build_frontend_type (TREE_TYPE (cst));
@@ -353,23 +354,23 @@ d_eval_constant_expression (tree cst)
real_value re = TREE_REAL_CST (TREE_REALPART (cst));
real_value im = TREE_REAL_CST (TREE_IMAGPART (cst));
complex_t value = complex_t (ldouble (re), ldouble (im));
- return ComplexExp::create (Loc (), value, type);
+ return ComplexExp::create (loc, value, type);
}
else if (code == INTEGER_CST)
{
dinteger_t value = TREE_INT_CST_LOW (cst);
- return IntegerExp::create (Loc (), value, type);
+ return IntegerExp::create (loc, value, type);
}
else if (code == REAL_CST)
{
real_value value = TREE_REAL_CST (cst);
- return RealExp::create (Loc (), ldouble (value), type);
+ return RealExp::create (loc, ldouble (value), type);
}
else if (code == STRING_CST)
{
const void *string = TREE_STRING_POINTER (cst);
size_t len = TREE_STRING_LENGTH (cst);
- return StringExp::create (Loc (), CONST_CAST (void *, string), len);
+ return StringExp::create (loc, CONST_CAST (void *, string), len);
}
else if (code == VECTOR_CST)
{
@@ -380,17 +381,31 @@ d_eval_constant_expression (tree cst)
for (size_t i = 0; i < nunits; i++)
{
Expression *elem
- = d_eval_constant_expression (VECTOR_CST_ELT (cst, i));
+ = d_eval_constant_expression (loc, VECTOR_CST_ELT (cst, i));
if (elem == NULL)
return NULL;
(*elements)[i] = elem;
}
- Expression *e = ArrayLiteralExp::create (Loc (), elements);
+ Expression *e = ArrayLiteralExp::create (loc, elements);
e->type = type->isTypeVector ()->basetype;
- return VectorExp::create (Loc (), e, type);
+ return VectorExp::create (loc, e, type);
+ }
+ else if (code == ADDR_EXPR)
+ {
+ /* Special handling for trees constructed by build_string_literal.
+ What we receive is an `&"string"[0]' expression, strip off the
+ outer ADDR_EXPR and ARRAY_REF to get to the underlying CST. */
+ tree pointee = TREE_OPERAND (cst, 0);
+
+ if (TREE_CODE (pointee) != ARRAY_REF
+ || TREE_OPERAND (pointee, 1) != integer_zero_node
+ || TREE_CODE (TREE_OPERAND (pointee, 0)) != STRING_CST)
+ return NULL;
+
+ return d_eval_constant_expression (loc, TREE_OPERAND (pointee, 0));
}
}
diff --git a/gcc/d/d-compiler.cc b/gcc/d/d-compiler.cc
index ffa7f78c82e..f737d8d9686 100644
--- a/gcc/d/d-compiler.cc
+++ b/gcc/d/d-compiler.cc
@@ -133,7 +133,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
cst = native_interpret_expr (vectype, buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL && e->op == TOKvector);
return e->isVectorExp ()->e1;
@@ -143,7 +143,7 @@ Compiler::paintAsType (UnionExp *, Expression *expr, Type *type)
/* Normal interpret cast. */
cst = native_interpret_expr (build_ctype (type), buffer, len);
- Expression *e = d_eval_constant_expression (cst);
+ Expression *e = d_eval_constant_expression (expr->loc, cst);
gcc_assert (e != NULL);
return e;
diff --git a/gcc/d/d-frontend.cc b/gcc/d/d-frontend.cc
index da34e902275..91335307150 100644
--- a/gcc/d/d-frontend.cc
+++ b/gcc/d/d-frontend.cc
@@ -195,7 +195,7 @@ eval_builtin (Loc loc, FuncDeclaration *fd, Expressions *arguments)
/* Builtin should be successfully evaluated.
Will only return NULL if we can't convert it. */
if (TREE_CONSTANT (result) && TREE_CODE (result) != CALL_EXPR)
- e = d_eval_constant_expression (result);
+ e = d_eval_constant_expression (loc, result);
return e;
}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index cd136524eb9..5424ad0ae28 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -44,6 +44,25 @@ along with GCC; see the file COPYING3. If not see
Target target;
+/* Table `__traits(getTargetInfo)' keys. */
+static vec<d_target_info_spec> target_info_table;
+
+/* Internal key handlers for `__traits(getTargetInfo)'. */
+static tree d_handle_target_cpp_std (void);
+static tree d_handle_target_cpp_runtime_library (void);
+
+/* In [traits/getTargetInfo], a reliable subset of getTargetInfo keys exists
+ which are always available. */
+static const struct d_target_info_spec d_language_target_info[] =
+{
+ /* { name, handler } */
+ { "cppStd", d_handle_target_cpp_std },
+ { "cppRuntimeLibrary", d_handle_target_cpp_runtime_library },
+ { "floatAbi", NULL },
+ { "objectFormat", NULL },
+ { NULL, NULL },
+};
+
/* Initialize the floating-point constants for TYPE. */
@@ -167,6 +186,12 @@ Target::_init (const Param &)
real_convert (&CTFloat::one.rv (), mode, &dconst1);
real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
+
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
+ d_add_target_info_handlers (d_language_target_info);
}
/* Return GCC memory alignment size for type TYPE. */
@@ -413,3 +438,68 @@ Target::toArgTypes (Type *)
/* Not implemented, however this is not currently used anywhere. */
return NULL;
}
+
+
+/* Add all target info in HANDLERS to TARGET_INFO_TABLE for use by
+ Target::getTargetInfo(). */
+
+void
+d_add_target_info_handlers (const d_target_info_spec *handlers)
+{
+ gcc_assert (handlers != NULL);
+
+ if (target_info_table.is_empty ())
+ target_info_table.create (8);
+
+ for (size_t i = 0; handlers[i].name != NULL; i++)
+ target_info_table.safe_push (handlers[i]);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppStd")'. */
+
+tree
+d_handle_target_cpp_std (void)
+{
+ return build_integer_cst (global.params.cplusplus);
+}
+
+/* Handle a call to `__traits(getTargetInfo, "cppRuntimeLibrary")'. */
+
+tree
+d_handle_target_cpp_runtime_library (void)
+{
+ /* The driver only ever optionally links to libstdc++. */
+ const char *libstdcxx = "libstdc++";
+ return build_string_literal (strlen (libstdcxx) + 1, libstdcxx);
+}
+
+/* Look up the target info KEY in the available getTargetInfo tables, and return
+ the result as an Expression, or NULL if KEY is not found. When the key must
+ always exist, but is not supported, an empty string expression is returned.
+ LOC is the location to use for the returned expression. */
+
+Expression *
+Target::getTargetInfo (const char *key, const Loc &loc)
+{
+ unsigned ix;
+ d_target_info_spec *spec;
+
+ FOR_EACH_VEC_ELT (target_info_table, ix, spec)
+ {
+ tree result;
+
+ if (strcmp (key, spec->name) != 0)
+ continue;
+
+ /* Get the requested information, or empty string if unhandled. */
+ if (spec->handler)
+ result = (spec->handler) ();
+ else
+ result = build_string_literal (1, "");
+
+ gcc_assert (result);
+ return d_eval_constant_expression (loc, result);
+ }
+
+ return NULL;
+}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index 728cba70335..4471d5155cc 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/d-target.h b/gcc/d/d-target.h
index d4413e47c61..8d3d6545a1c 100644
--- a/gcc/d/d-target.h
+++ b/gcc/d/d-target.h
@@ -31,4 +31,19 @@ extern struct gcc_targetdm targetdm;
/* Used by target to add predefined version idenditiers. */
extern void d_add_builtin_version (const char *);
+/* Structure describing a supported key for `__traits(getTargetInfo)' and a
+ function to handle it. */
+struct d_target_info_spec
+{
+ /* The name of the key or NULL to mark the end of a table of keys. */
+ const char *name;
+ /* Function to handle this key, the return value of the handler must be a CST.
+ This pointer may be NULL if no special handling is required, for instance,
+ the key must always be available according to the D language spec. */
+ tree (*handler) ();
+};
+
+/* Used by target to add getTargetInfo handlers. */
+extern void d_add_target_info_handlers (const d_target_info_spec *);
+
#endif /* GCC_D_TARGET_H */
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 31fe5181912..f5cf9d3f214 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -496,7 +496,7 @@ extern void d_init_builtins (void);
extern void d_register_builtin_type (tree, const char *);
extern void d_build_builtins_module (Module *);
extern void d_maybe_set_builtin (Module *);
-extern Expression *d_eval_constant_expression (tree);
+extern Expression *d_eval_constant_expression (const Loc &, tree);
extern void d_init_versions (void);
/* In d-codegen.cc. */
diff --git a/gcc/d/dmd/idgen.c b/gcc/d/dmd/idgen.c
index 16f3b5f29ec..316c5e3b0dd 100644
--- a/gcc/d/dmd/idgen.c
+++ b/gcc/d/dmd/idgen.c
@@ -360,6 +360,7 @@ Msgtable msgtable[] =
{ "getUnitTests", NULL },
{ "getVirtualIndex", NULL },
{ "getPointerBitmap", NULL },
+ { "getTargetInfo", NULL },
// For C++ mangling
{ "allocator", NULL },
diff --git a/gcc/d/dmd/target.h b/gcc/d/dmd/target.h
index f2a55d6a134..20b505220e7 100644
--- a/gcc/d/dmd/target.h
+++ b/gcc/d/dmd/target.h
@@ -105,6 +105,7 @@ public:
// ABI and backend.
LINK systemLinkage();
TypeTuple *toArgTypes(Type *t);
+ Expression *getTargetInfo(const char* name, const Loc& loc);
};
extern Target target;
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index bc1e2c3c234..f859749be14 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
@@ -265,6 +266,7 @@ TraitsInitializer::TraitsInitializer()
"getUnitTests",
"getVirtualIndex",
"getPointerBitmap",
+ "getTargetInfo",
NULL
};
@@ -1471,6 +1473,28 @@ Expression *semanticTraits(TraitsExp *e, Scope *sc)
{
return pointerBitmap(e);
}
+ else if (e->ident == Id::getTargetInfo)
+ {
+ if (dim != 1)
+ return dimError(e, 1, dim);
+
+ Expression *ex = isExpression((*e->args)[0]);
+ StringExp *se = ex ? ex->ctfeInterpret()->toStringExp() : NULL;
+ if (!ex || !se || se->len == 0)
+ {
+ e->error("string expected as argument of __traits `%s` instead of `%s`", e->ident->toChars(), ex->toChars());
+ return new ErrorExp();
+ }
+ se = se->toUTF8(sc);
+
+ Expression *r = target.getTargetInfo(se->toPtr(), e->loc);
+ if (!r)
+ {
+ e->error("`getTargetInfo` key `\"%s\"` not supported by this implementation", se->toPtr());
+ return new ErrorExp();
+ }
+ return semantic(r, sc);
+ }
if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars))
e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub);
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 900d584d178..6874fafa48b 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10804,6 +10804,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ad568581fd4..a14ae7780a5 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f7086f2..3f5cb2a8241 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -151,7 +151,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-01-11 11:39 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-01-11 11:39 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:7b1d78f699ac71861335f5e4da6e256cc0601b8b
commit 7b1d78f699ac71861335f5e4da6e256cc0601b8b
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++
gcc/config/arm/arm-d.c | 53 +++++++++++++++++++++++----
gcc/config/darwin-d.c | 26 +++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 +-
gcc/config/mips/mips-d.c | 30 +++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++
gcc/config/riscv/riscv-d.c | 46 +++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 +++++++++++++++
gcc/config/s390/s390-d.c | 30 +++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++
gcc/d/d-target.cc | 2 +
gcc/d/d-target.def | 20 ++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++
gcc/doc/tm.texi.in | 4 ++
libphobos/libdruntime/core/sys/posix/setjmp.d | 3 +-
23 files changed, 491 insertions(+), 9 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..190f6037d42 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..4ecab686cf3 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 425ca8365ba..c39f6897223 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..ac031a08640 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..92549cb4522 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 8dd0354309e..4c6c6002ee5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..205ee5359c5 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..80c36153a9f 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..c3fc08edf75 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..3576f479c79 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..dbd8a34c427 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..118d398a60f 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..d8ca6fbc0ef 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -189,6 +189,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..55b7a830bb0 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 5fd4b486a9b..ba666813195 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 062785af1e2..f3937230813 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10804,6 +10804,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3b19e6f4281..569cadba798 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
diff --git a/libphobos/libdruntime/core/sys/posix/setjmp.d b/libphobos/libdruntime/core/sys/posix/setjmp.d
index 38d4f7086f2..3f5cb2a8241 100644
--- a/libphobos/libdruntime/core/sys/posix/setjmp.d
+++ b/libphobos/libdruntime/core/sys/posix/setjmp.d
@@ -151,7 +151,8 @@ version (CRuntime_Glibc)
c_long __pc;
c_long[12] __regs;
c_long __sp;
- double[12] __fpregs;
+ static if (__traits(getTargetInfo, "floatAbi") == "double")
+ double[12] __fpregs;
}
alias __jmp_buf = __riscv_jmp_buf[1];
}
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-01-28 17:31 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-01-28 17:31 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:e7cfe1602934ec7fc0498dbd2bfd209babb112c4
commit e7cfe1602934ec7fc0498dbd2bfd209babb112c4
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++++++++
gcc/config/arm/arm-d.c | 53 ++++++++++++++++++++++++++++++++++++------
gcc/config/darwin-d.c | 26 +++++++++++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 ++-
gcc/config/mips/mips-d.c | 30 ++++++++++++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++++++++++
gcc/d/d-target.cc | 2 ++
gcc/d/d-target.def | 20 ++++++++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++++++
gcc/doc/tm.texi.in | 4 ++++
22 files changed, 489 insertions(+), 8 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..190f6037d42 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..4ecab686cf3 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 425ca8365ba..c39f6897223 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..ac031a08640 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..92549cb4522 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 272b1957b47..d51d4b243b8 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..205ee5359c5 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..80c36153a9f 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..c3fc08edf75 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..3576f479c79 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..dbd8a34c427 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..118d398a60f 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..d8ca6fbc0ef 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -189,6 +189,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..55b7a830bb0 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 70f7f2cb582..992f8e885fa 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 062785af1e2..f3937230813 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10804,6 +10804,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3b19e6f4281..569cadba798 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-01-30 19:08 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-01-30 19:08 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:35d5aa19902a4101ca27287d97753788554225ad
commit 35d5aa19902a4101ca27287d97753788554225ad
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++++++++
gcc/config/arm/arm-d.c | 53 ++++++++++++++++++++++++++++++++++++------
gcc/config/darwin-d.c | 26 +++++++++++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 ++-
gcc/config/mips/mips-d.c | 30 ++++++++++++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++++++++++
gcc/d/d-target.cc | 2 ++
gcc/d/d-target.def | 20 ++++++++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++++++
gcc/doc/tm.texi.in | 4 ++++
22 files changed, 489 insertions(+), 8 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..190f6037d42 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..4ecab686cf3 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 425ca8365ba..c39f6897223 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..ac031a08640 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..92549cb4522 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 272b1957b47..d51d4b243b8 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..205ee5359c5 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..80c36153a9f 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..c3fc08edf75 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..3576f479c79 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..dbd8a34c427 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..118d398a60f 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..d8ca6fbc0ef 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -189,6 +189,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..55b7a830bb0 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 70f7f2cb582..992f8e885fa 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 062785af1e2..f3937230813 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10804,6 +10804,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 3b19e6f4281..569cadba798 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7355,6 +7355,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-03-07 17:01 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-03-07 17:01 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:a86896ba2b46f09cada224816e3bf75eef10d59a
commit a86896ba2b46f09cada224816e3bf75eef10d59a
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++++++++
gcc/config/arm/arm-d.c | 53 ++++++++++++++++++++++++++++++++++++------
gcc/config/darwin-d.c | 26 +++++++++++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 ++-
gcc/config/mips/mips-d.c | 30 ++++++++++++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++++++++++
gcc/d/d-target.cc | 2 ++
gcc/d/d-target.def | 20 ++++++++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++++++
gcc/doc/tm.texi.in | 4 ++++
22 files changed, 489 insertions(+), 8 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..190f6037d42 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..4ecab686cf3 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 425ca8365ba..c39f6897223 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..ac031a08640 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..92549cb4522 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 69fddcafd31..38d01404f4c 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..205ee5359c5 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..80c36153a9f 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..c3fc08edf75 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..3576f479c79 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..dbd8a34c427 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..118d398a60f 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..d8ca6fbc0ef 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -189,6 +189,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..55b7a830bb0 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index b7c612c2af2..acffce7bd69 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..e8036b78a63 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..9c8cd125a05 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-03-14 22:00 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-03-14 22:00 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:f9e239ad805469255a765f1f8a7a413126c48156
commit f9e239ad805469255a765f1f8a7a413126c48156
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++++++++
gcc/config/arm/arm-d.c | 53 ++++++++++++++++++++++++++++++++++++------
gcc/config/darwin-d.c | 26 +++++++++++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 3 ++-
gcc/config/mips/mips-d.c | 30 ++++++++++++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++++++++++
gcc/d/d-target.cc | 2 ++
gcc/d/d-target.def | 20 ++++++++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++++++
gcc/doc/tm.texi.in | 4 ++++
22 files changed, 489 insertions(+), 8 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 5c9b4fa6fb8..190f6037d42 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -29,3 +29,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 76ede3b6d44..4ecab686cf3 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -36,18 +36,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 425ca8365ba..c39f6897223 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -36,7 +36,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index cbd3ceb187d..ac031a08640 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -42,3 +42,31 @@ ix86_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 9f8a69ea7dc..92549cb4522 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
/* In winnt.c */
extern void i386_pe_unique_section (tree, int);
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 69fddcafd31..38d01404f4c 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -799,8 +799,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target Pragmas. */
#define REGISTER_TARGET_PRAGMAS() ix86_register_pragmas ()
-/* Target CPU versions for D. */
+/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#ifndef CC1_SPEC
#define CC1_SPEC "%(cc1_cpu) "
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dad101cf7eb..205ee5359c5 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -54,3 +54,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 1de49df12cc..80c36153a9f 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -37,3 +37,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index 2b690b18cfd..c3fc08edf75 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -37,3 +37,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 14c4133f305..3576f479c79 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -43,3 +43,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 155144ce7b8..dbd8a34c427 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -39,3 +39,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 186e965ae84..118d398a60f 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -46,3 +46,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index d50fcef22e2..d8ca6fbc0ef 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -189,6 +189,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index d1426a17e99..55b7a830bb0 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index b7c612c2af2..acffce7bd69 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index b272fa4806d..e8036b78a63 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index bf724dc093c..9c8cd125a05 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-04-10 15:04 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-04-10 15:04 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:5baeaa40648f852b2838a99ec3d0a0acb4be002a
commit 5baeaa40648f852b2838a99ec3d0a0acb4be002a
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/aarch64/aarch64-d.c | 23 ++++++++++++++++++
gcc/config/arm/arm-d.c | 53 ++++++++++++++++++++++++++++++++++++------
gcc/config/darwin-d.c | 26 +++++++++++++++++++++
gcc/config/dragonfly-d.c | 26 +++++++++++++++++++++
gcc/config/freebsd-d.c | 26 +++++++++++++++++++++
gcc/config/glibc-d.c | 26 +++++++++++++++++++++
gcc/config/i386/i386-d.c | 28 ++++++++++++++++++++++
gcc/config/i386/i386-protos.h | 1 +
gcc/config/i386/i386.h | 1 +
gcc/config/mips/mips-d.c | 30 ++++++++++++++++++++++++
gcc/config/netbsd-d.c | 26 +++++++++++++++++++++
gcc/config/pa/pa-d.c | 28 ++++++++++++++++++++++
gcc/config/riscv/riscv-d.c | 46 ++++++++++++++++++++++++++++++++++++
gcc/config/rs6000/rs6000-d.c | 30 ++++++++++++++++++++++++
gcc/config/s390/s390-d.c | 30 ++++++++++++++++++++++++
gcc/config/sol2-d.c | 26 +++++++++++++++++++++
gcc/config/sparc/sparc-d.c | 28 ++++++++++++++++++++++
gcc/d/d-target.cc | 2 ++
gcc/d/d-target.def | 20 ++++++++++++++++
gcc/d/dmd/traits.c | 1 +
gcc/doc/tm.texi | 14 +++++++++++
gcc/doc/tm.texi.in | 4 ++++
22 files changed, 488 insertions(+), 7 deletions(-)
diff --git a/gcc/config/aarch64/aarch64-d.c b/gcc/config/aarch64/aarch64-d.c
index 4fce593ac27..416bb7c8033 100644
--- a/gcc/config/aarch64/aarch64-d.c
+++ b/gcc/config/aarch64/aarch64-d.c
@@ -31,3 +31,26 @@ aarch64_d_target_versions (void)
d_add_builtin_version ("AArch64");
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+aarch64_d_handle_target_float_abi (void)
+{
+ const char *abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+aarch64_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", aarch64_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 2cb9f4bd899..485b1b4d20a 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -38,18 +38,57 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+arm_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (arm_float_abi)
+ {
+ case ARM_FLOAT_ABI_HARD:
+ abi = "hard";
+ break;
+
+ case ARM_FLOAT_ABI_SOFT:
+ abi = "soft";
+ break;
+
+ case ARM_FLOAT_ABI_SOFTFP:
+ abi = "softfp";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+arm_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", arm_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/darwin-d.c b/gcc/config/darwin-d.c
index afc32da4ad8..67d69b721b5 100644
--- a/gcc/config/darwin-d.c
+++ b/gcc/config/darwin-d.c
@@ -32,9 +32,35 @@ darwin_d_os_builtins (void)
d_add_builtin_version ("darwin");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+darwin_d_handle_target_object_format (void)
+{
+ const char *objfmt = "macho";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Darwin targets. */
+
+static void
+darwin_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", darwin_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS darwin_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO darwin_d_register_target_info
+
/* Define TARGET_D_MINFO_SECTION for Darwin targets. */
#undef TARGET_D_MINFO_SECTION
diff --git a/gcc/config/dragonfly-d.c b/gcc/config/dragonfly-d.c
index 76f4cc02ff7..dc301b54e8f 100644
--- a/gcc/config/dragonfly-d.c
+++ b/gcc/config/dragonfly-d.c
@@ -31,7 +31,33 @@ dragonfly_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+dragonfly_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for DragonFly targets. */
+
+static void
+dragonfly_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", dragonfly_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS dragonfly_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO dragonfly_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/freebsd-d.c b/gcc/config/freebsd-d.c
index 8a8ddd92884..8bebe79c895 100644
--- a/gcc/config/freebsd-d.c
+++ b/gcc/config/freebsd-d.c
@@ -37,7 +37,33 @@ freebsd_d_os_builtins (void)
d_add_builtin_version ("Posix");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+freebsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for FreeBSD targets. */
+
+static void
+freebsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", freebsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS freebsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO freebsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/glibc-d.c b/gcc/config/glibc-d.c
index 092c5d805a6..c98d494cd77 100644
--- a/gcc/config/glibc-d.c
+++ b/gcc/config/glibc-d.c
@@ -42,7 +42,33 @@ glibc_d_os_builtins (void)
#endif
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+glibc_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Glibc targets. */
+
+static void
+glibc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", glibc_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS glibc_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO glibc_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/i386/i386-d.c b/gcc/config/i386/i386-d.c
index 58b4790fdad..da5958c3e7d 100644
--- a/gcc/config/i386/i386-d.c
+++ b/gcc/config/i386/i386-d.c
@@ -45,6 +45,34 @@ ix86_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+ix86_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (! (TARGET_80387 || TARGET_FLOAT_RETURNS_IN_80387))
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+ix86_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", ix86_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
/* Implement TARGET_D_HAS_STDCALL_CONVENTION for x86 targets. */
bool
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index acfb9f5fe87..7782cf1163f 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -264,6 +264,7 @@ extern void ix86_register_pragmas (void);
/* In i386-d.c */
extern void ix86_d_target_versions (void);
+extern void ix86_d_register_target_info (void);
extern bool ix86_d_has_stdcall_convention (unsigned int *, unsigned int *);
/* In winnt.c */
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 17e233a4e74..13174e7aa70 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -803,6 +803,7 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
/* Target hooks for D language. */
#define TARGET_D_CPU_VERSIONS ix86_d_target_versions
+#define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
#define TARGET_D_HAS_STDCALL_CONVENTION ix86_d_has_stdcall_convention
#ifndef CC1_SPEC
diff --git a/gcc/config/mips/mips-d.c b/gcc/config/mips/mips-d.c
index dc57127791c..e03f48602ef 100644
--- a/gcc/config/mips/mips-d.c
+++ b/gcc/config/mips/mips-d.c
@@ -56,3 +56,33 @@ mips_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+mips_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT_ABI)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT_ABI)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+mips_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", mips_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/netbsd-d.c b/gcc/config/netbsd-d.c
index c3ac01067fe..090586c673f 100644
--- a/gcc/config/netbsd-d.c
+++ b/gcc/config/netbsd-d.c
@@ -33,7 +33,33 @@ netbsd_d_os_builtins (void)
d_add_builtin_version ("NetBSD");
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+netbsd_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for NetBSD targets. */
+
+static void
+netbsd_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", netbsd_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS netbsd_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO netbsd_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/pa/pa-d.c b/gcc/config/pa/pa-d.c
index 663e749995a..41b2f1848e7 100644
--- a/gcc/config/pa/pa-d.c
+++ b/gcc/config/pa/pa-d.c
@@ -39,3 +39,31 @@ pa_d_target_versions (void)
else
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+pa_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "hard";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+pa_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", pa_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/riscv/riscv-d.c b/gcc/config/riscv/riscv-d.c
index b20b778bd35..8883cec2847 100644
--- a/gcc/config/riscv/riscv-d.c
+++ b/gcc/config/riscv/riscv-d.c
@@ -39,3 +39,49 @@ riscv_d_target_versions (void)
else
d_add_builtin_version ("D_SoftFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+riscv_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ switch (riscv_abi)
+ {
+ case ABI_ILP32E:
+ case ABI_ILP32:
+ case ABI_LP64:
+ abi = "soft";
+ break;
+
+ case ABI_ILP32F:
+ case ABI_LP64F:
+ abi = "single";
+ break;
+
+ case ABI_ILP32D:
+ case ABI_LP64D:
+ abi = "double";
+ break;
+
+ default:
+ abi = "";
+ break;
+ }
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+riscv_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", riscv_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/rs6000/rs6000-d.c b/gcc/config/rs6000/rs6000-d.c
index 6bfe8130dd3..755de42733b 100644
--- a/gcc/config/rs6000/rs6000-d.c
+++ b/gcc/config/rs6000/rs6000-d.c
@@ -45,3 +45,33 @@ rs6000_d_target_versions (void)
d_add_builtin_version ("D_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+rs6000_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+rs6000_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", rs6000_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/s390/s390-d.c b/gcc/config/s390/s390-d.c
index 2f945ebfa12..1a990636aa1 100644
--- a/gcc/config/s390/s390-d.c
+++ b/gcc/config/s390/s390-d.c
@@ -41,3 +41,33 @@ s390_d_target_versions (void)
else if (TARGET_HARD_FLOAT)
d_add_builtin_version ("D_HardFloat");
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+s390_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_HARD_FLOAT)
+ abi = "hard";
+ else if (TARGET_SOFT_FLOAT)
+ abi = "soft";
+ else
+ abi = "";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+s390_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", s390_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/config/sol2-d.c b/gcc/config/sol2-d.c
index 529d365296c..650cb371927 100644
--- a/gcc/config/sol2-d.c
+++ b/gcc/config/sol2-d.c
@@ -33,7 +33,33 @@ solaris_d_os_builtins (void)
d_add_builtin_version ("Solaris"); \
}
+/* Handle a call to `__traits(getTargetInfo, "objectFormat")'. */
+
+static tree
+solaris_d_handle_target_object_format (void)
+{
+ const char *objfmt = "elf";
+
+ return build_string_literal (strlen (objfmt) + 1, objfmt);
+}
+
+/* Implement TARGET_D_REGISTER_OS_TARGET_INFO for Solaris targets. */
+
+static void
+solaris_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "objectFormat", solaris_d_handle_target_object_format },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
+
#undef TARGET_D_OS_VERSIONS
#define TARGET_D_OS_VERSIONS solaris_d_os_builtins
+#undef TARGET_D_REGISTER_OS_TARGET_INFO
+#define TARGET_D_REGISTER_OS_TARGET_INFO solaris_d_register_target_info
+
struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
diff --git a/gcc/config/sparc/sparc-d.c b/gcc/config/sparc/sparc-d.c
index 0eb663bb132..cfb8daee25e 100644
--- a/gcc/config/sparc/sparc-d.c
+++ b/gcc/config/sparc/sparc-d.c
@@ -48,3 +48,31 @@ sparc_d_target_versions (void)
d_add_builtin_version ("SPARC_SoftFloat");
}
}
+
+/* Handle a call to `__traits(getTargetInfo, "floatAbi")'. */
+
+static tree
+sparc_d_handle_target_float_abi (void)
+{
+ const char *abi;
+
+ if (TARGET_FPU)
+ abi = "hard";
+ else
+ abi = "soft";
+
+ return build_string_literal (strlen (abi) + 1, abi);
+}
+
+/* Implement TARGET_D_REGISTER_CPU_TARGET_INFO. */
+
+void
+sparc_d_register_target_info (void)
+{
+ const struct d_target_info_spec handlers[] = {
+ { "floatAbi", sparc_d_handle_target_float_abi },
+ { NULL, NULL },
+ };
+
+ d_add_target_info_handlers (handlers);
+}
diff --git a/gcc/d/d-target.cc b/gcc/d/d-target.cc
index f1814df110d..be354d9f1f0 100644
--- a/gcc/d/d-target.cc
+++ b/gcc/d/d-target.cc
@@ -198,6 +198,8 @@ Target::_init (const Param &)
/* Initialize target info tables, the keys required by the language are added
last, so that the OS and CPU handlers can override. */
+ targetdm.d_register_cpu_target_info ();
+ targetdm.d_register_os_target_info ();
d_add_target_info_handlers (d_language_target_info);
}
diff --git a/gcc/d/d-target.def b/gcc/d/d-target.def
index f79ffb9cd7d..aa6bf55e6e6 100644
--- a/gcc/d/d-target.def
+++ b/gcc/d/d-target.def
@@ -46,6 +46,26 @@ relating to the target operating system.",
void, (void),
hook_void_void)
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(d_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{d_add_target_info_handlers}, which takes a\n\
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys\n\
+added by this hook are made available at compile time by the\n\
+@code{__traits(getTargetInfo)} extension, the result is an expression\n\
+describing the requested target information.",
+ void, (void),
+ hook_void_void)
+
+/* getTargetInfo keys relating to the target OS. */
+DEFHOOK
+(d_register_os_target_info,
+ "Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
/* ModuleInfo section name and brackets. */
DEFHOOKPOD
(d_minfo_section,
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 5a9f58b79f5..98cb6e4d48b 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 71607c4dc4e..97c8eebcd6f 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -10808,6 +10808,20 @@ Similarly to @code{TARGET_D_CPU_VERSIONS}, but is used for versions
relating to the target operating system.
@end deftypefn
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{d_add_target_info_handlers}, which takes a
+@samp{struct d_target_info_spec} (defined in @file{d/d-target.h}). The keys
+added by this hook are made available at compile time by the
+@code{__traits(getTargetInfo)} extension, the result is an expression
+describing the requested target information.
+@end deftypefn
+
+@deftypefn {D Target Hook} void TARGET_D_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_D_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@deftypevr {D Target Hook} {const char *} TARGET_D_MINFO_SECTION
Contains the name of the section in which module info references should be
placed. This section is expected to be bracketed by two symbols to indicate
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index c8880dafcd4..e2d49ee9f57 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -7357,6 +7357,10 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_D_OS_VERSIONS
+@hook TARGET_D_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_D_REGISTER_OS_TARGET_INFO
+
@hook TARGET_D_MINFO_SECTION
@hook TARGET_D_MINFO_START_NAME
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-04-10 17:00 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-04-10 17:00 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8e07eda37accbbd9411aafc28b20e54a413e779a
commit 8e07eda37accbbd9411aafc28b20e54a413e779a
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/arm/arm-d.c | 11 ++++-------
gcc/d/dmd/traits.c | 1 +
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 5f43ef9b179..485b1b4d20a 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -38,15 +38,12 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 5a9f58b79f5..98cb6e4d48b 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-04-19 18:05 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-04-19 18:05 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9bf7b59bc8662e2ed5a2eb0c4e0116fbb44c5d22
commit 9bf7b59bc8662e2ed5a2eb0c4e0116fbb44c5d22
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/arm/arm-d.c | 11 ++++-------
gcc/d/dmd/traits.c | 1 +
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 5f43ef9b179..485b1b4d20a 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -38,15 +38,12 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 5a9f58b79f5..98cb6e4d48b 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
^ permalink raw reply [flat|nested] 14+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo)
@ 2021-09-17 14:34 Iain Buclaw
0 siblings, 0 replies; 14+ messages in thread
From: Iain Buclaw @ 2021-09-17 14:34 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8f9a5380dded09e2d92667c48daa59f6acdd3178
commit 8f9a5380dded09e2d92667c48daa59f6acdd3178
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Fri Dec 4 23:04:21 2020 +0100
d: Implement __traits(getTargetInfo)
Diff:
---
gcc/config/arm/arm-d.c | 11 ++++-------
gcc/d/dmd/traits.c | 1 +
2 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/gcc/config/arm/arm-d.c b/gcc/config/arm/arm-d.c
index 5f43ef9b179..485b1b4d20a 100644
--- a/gcc/config/arm/arm-d.c
+++ b/gcc/config/arm/arm-d.c
@@ -38,15 +38,12 @@ arm_d_target_versions (void)
d_add_builtin_version ("ARM_Thumb");
}
- if (TARGET_HARD_FLOAT_ABI)
+ if (arm_float_abi == ARM_FLOAT_ABI_HARD)
d_add_builtin_version ("ARM_HardFloat");
- else
- {
- if (TARGET_SOFT_FLOAT)
- d_add_builtin_version ("ARM_SoftFloat");
- else if (TARGET_HARD_FLOAT)
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFT)
+ d_add_builtin_version ("ARM_SoftFloat");
+ else if (arm_float_abi == ARM_FLOAT_ABI_SOFTFP)
d_add_builtin_version ("ARM_SoftFP");
- }
if (TARGET_SOFT_FLOAT)
d_add_builtin_version ("D_SoftFloat");
diff --git a/gcc/d/dmd/traits.c b/gcc/d/dmd/traits.c
index 5a9f58b79f5..98cb6e4d48b 100644
--- a/gcc/d/dmd/traits.c
+++ b/gcc/d/dmd/traits.c
@@ -31,6 +31,7 @@
#include "module.h"
#include "attrib.h"
#include "parse.h"
+#include "target.h"
#include "root/speller.h"
#include "target.h"
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2021-09-17 14:34 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-04 22:04 [gcc(refs/users/ibuclaw/heads/darwin)] d: Implement __traits(getTargetInfo) Iain Buclaw
2020-12-04 23:08 Iain Buclaw
2020-12-05 23:47 Iain Buclaw
2020-12-09 9:51 Iain Buclaw
2020-12-22 13:40 Iain Buclaw
2021-01-11 11:39 Iain Buclaw
2021-01-28 17:31 Iain Buclaw
2021-01-30 19:08 Iain Buclaw
2021-03-07 17:01 Iain Buclaw
2021-03-14 22:00 Iain Buclaw
2021-04-10 15:04 Iain Buclaw
2021-04-10 17:00 Iain Buclaw
2021-04-19 18:05 Iain Buclaw
2021-09-17 14:34 Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).