diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 059cf2e8f79f4..68a09cfaf10bd 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -604,6 +604,8 @@ tm_d_file_list=@tm_d_file_list@
tm_d_include_list=@tm_d_include_list@
tm_rust_file_list=@tm_rust_file_list@
tm_rust_include_list=@tm_rust_include_list@
+tm_jit_file_list=@tm_jit_file_list@
+tm_jit_include_list=@tm_jit_include_list@
build_xm_file_list=@build_xm_file_list@
build_xm_include_list=@build_xm_include_list@
build_xm_defines=@build_xm_defines@
@@ -903,6 +905,7 @@ TCONFIG_H = tconfig.h $(xm_file_list)
TM_P_H = tm_p.h $(tm_p_file_list) $(TREE_H)
TM_D_H = tm_d.h $(tm_d_file_list)
TM_RUST_H = tm_rust.h $(tm_rust_file_list)
+TM_JIT_H = tm_jit.h $(tm_jit_file_list)
GTM_H = tm.h $(tm_file_list) insn-constants.h
TM_H = $(GTM_H) insn-flags.h $(OPTIONS_H)
@@ -962,11 +965,13 @@ C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h
COMMON_TARGET_DEF = common/common-target.def target-hooks-macros.h
D_TARGET_DEF = d/d-target.def target-hooks-macros.h
RUST_TARGET_DEF = rust/rust-target.def target-hooks-macros.h
+JIT_TARGET_DEF = jit/jit-target.def target-hooks-macros.h
TARGET_H = $(TM_H) target.h $(TARGET_DEF) insn-modes.h insn-codes.h
C_TARGET_H = c-family/c-target.h $(C_TARGET_DEF)
COMMON_TARGET_H = common/common-target.h $(INPUT_H) $(COMMON_TARGET_DEF)
D_TARGET_H = d/d-target.h $(D_TARGET_DEF)
RUST_TARGET_H = rust/rust-target.h $(RUST_TARGET_DEF)
+JIT_TARGET_H = jit/jit-target.h $(JIT_TARGET_DEF)
MACHMODE_H = machmode.h mode-classes.def
HOOKS_H = hooks.h
HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
@@ -1280,6 +1285,9 @@ CXX_TARGET_OBJS=@cxx_target_objs@
# Target specific, D specific object file
D_TARGET_OBJS=@d_target_objs@
+# Target specific, JIT specific object file
+JIT_TARGET_OBJS=@jit_target_objs@
+
# Target specific, Fortran specific object file
FORTRAN_TARGET_OBJS=@fortran_target_objs@
@@ -2042,6 +2050,7 @@ tm.h: cs-tm.h ; @true
tm_p.h: cs-tm_p.h ; @true
tm_d.h: cs-tm_d.h ; @true
tm_rust.h: cs-tm_rust.h ; @true
+tm_jit.h: cs-tm_jit.h ; @true
cs-config.h: Makefile
TARGET_CPU_DEFAULT="" \
@@ -2081,6 +2090,11 @@ cs-tm_rust.h: Makefile
HEADERS="$(tm_rust_include_list)" DEFINES="" \
$(SHELL) $(srcdir)/mkconfig.sh tm_rust.h
+cs-tm_jit.h: Makefile
+ TARGET_CPU_DEFAULT="" \
+ HEADERS="$(tm_jit_include_list)" DEFINES="" \
+ $(SHELL) $(srcdir)/mkconfig.sh tm_jit.h
+
# Don't automatically run autoconf, since configure.ac might be accidentally
# newer than configure. Also, this writes into the source directory which
# might be on a read-only file system. If configured for maintainer mode
@@ -2417,6 +2431,12 @@ default-d.o: config/default-d.cc
$(COMPILE) $<
$(POSTCOMPILE)
+# Files used by the JIT language front end.
+
+default-jit.o: config/default-jit.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
# Files used by the Rust language front end.
default-rust.o: config/default-rust.cc
@@ -2756,6 +2776,15 @@ s-rust-target-hooks-def-h: build/genhooks$(build_exeext)
rust/rust-target-hooks-def.h
$(STAMP) s-rust-target-hooks-def-h
+jit/jit-target-hooks-def.h: s-jit-target-hooks-def-h; @true
+
+s-jit-target-hooks-def-h: build/genhooks$(build_exeext)
+ $(RUN_GEN) build/genhooks$(build_exeext) "JIT Target Hook" \
+ > tmp-jit-target-hooks-def.h
+ $(SHELL) $(srcdir)/../move-if-change tmp-jit-target-hooks-def.h \
+ jit/jit-target-hooks-def.h
+ $(STAMP) s-jit-target-hooks-def-h
+
# check if someone mistakenly only changed tm.texi.
# We use a different pathname here to avoid a circular dependency.
s-tm-texi: $(srcdir)/doc/../doc/tm.texi
@@ -2950,8 +2979,8 @@ s-gtype: $(EXTRA_GTYPE_DEPS) build/gengtype$(build_exeext) \
-r gtype.state
$(STAMP) s-gtype
-generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \
- $(simple_generated_h) specs.h \
+generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_JIT_H) $(TM_H) \
+ multilib.h $(simple_generated_h) specs.h \
tree-check.h genrtl.h insn-modes.h insn-modes-inline.h \
tm-preds.h tm-constrs.h \
$(ALL_GTFILES_H) gtype-desc.cc gtype-desc.h version.h \
@@ -2962,6 +2991,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \
c-family/c-target-hooks-def.h d/d-target-hooks-def.h \
$(TM_RUST_H) rust/rust-target-hooks-def.h \
case-cfn-macros.h \
+ jit/jit-target-hooks-def.h case-cfn-macros.h \
cfn-operators.pd omp-device-properties.h
#
@@ -3095,8 +3125,8 @@ build/genrecog.o : genrecog.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
$(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H) \
$(HASH_TABLE_H) inchash.h
build/genhooks.o : genhooks.cc $(TARGET_DEF) $(C_TARGET_DEF) \
- $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(BCONFIG_H) \
- $(SYSTEM_H) errors.h
+ $(COMMON_TARGET_DEF) $(D_TARGET_DEF) $(RUST_TARGET_DEF) $(JIT_TARGET_DEF) \
+ $(BCONFIG_H) $(SYSTEM_H) errors.h
build/genmddump.o : genmddump.cc $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \
$(CORETYPES_H) $(GTM_H) errors.h $(READ_MD_H) $(GENSUPPORT_H)
build/genmatch.o : genmatch.cc $(BCONFIG_H) $(SYSTEM_H) $(CORETYPES_H) \
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 71ac3badafd9c..91847df8217b6 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -149,6 +149,9 @@
# d_target_objs List of extra target-dependent objects that be
# linked into the D compiler only.
#
+# jit_target_objs List of extra target-dependent objects that be
+# linked into the jit compiler only.
+#
# fortran_target_objs List of extra target-dependent objects that be
# linked into the fortran compiler only.
#
@@ -210,6 +213,9 @@
#
# target_has_targetrustm Set to yes or no depending on whether the target
# has its own definition of targetrustm.
+#
+# target_has_targetjitm Set to yes or no depending on whether the target
+# has its own definition of targetdm.
out_file=
common_out_file=
@@ -226,12 +232,14 @@ extra_options=
c_target_objs=
cxx_target_objs=
d_target_objs=
+jit_target_objs=
fortran_target_objs=
rust_target_objs=
target_has_targetcm=no
target_has_targetm_common=yes
target_has_targetdm=no
target_has_targetrustm=no
+target_has_targetjitm=no
tm_defines=
xm_defines=
# Set this to force installation and use of collect2.
@@ -381,6 +389,7 @@ arm*-*-*)
c_target_objs="arm-c.o"
cxx_target_objs="arm-c.o"
d_target_objs="arm-d.o"
+ #jit_target_objs="arm-jit.o"
extra_options="${extra_options} arm/arm-tables.opt"
target_gtfiles="\$(srcdir)/config/arm/arm-builtins.cc \$(srcdir)/config/arm/arm-mve-builtins.h \$(srcdir)/config/arm/arm-mve-builtins.cc"
;;
@@ -416,6 +425,7 @@ i[34567]86-*-* | x86_64-*-*)
c_target_objs="i386-c.o"
cxx_target_objs="i386-c.o"
d_target_objs="i386-d.o"
+ jit_target_objs="i386-jit.o"
extra_objs="x86-tune-sched.o x86-tune-sched-bd.o x86-tune-sched-atom.o x86-tune-sched-core.o i386-options.o i386-builtins.o i386-expand.o i386-features.o"
target_gtfiles="\$(srcdir)/config/i386/i386-builtins.cc \$(srcdir)/config/i386/i386-expand.cc \$(srcdir)/config/i386/i386-options.cc"
extra_options="${extra_options} fused-madd.opt"
@@ -485,6 +495,7 @@ microblaze*-*-*)
mips*-*-*)
cpu_type=mips
d_target_objs="mips-d.o"
+ #jit_target_objs="mips-jit.o"
extra_headers="loongson.h loongson-mmiintrin.h msa.h"
extra_objs="frame-header-opt.o"
extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt"
@@ -574,11 +585,13 @@ sparc*-*-*)
c_target_objs="sparc-c.o"
cxx_target_objs="sparc-c.o"
d_target_objs="sparc-d.o"
+ #jit_target_objs="sparc-jit.o"
extra_headers="visintrin.h"
;;
s390*-*-*)
cpu_type=s390
d_target_objs="s390-d.o"
+ #jit_target_objs="s390-jit.o"
extra_options="${extra_options} fused-madd.opt"
extra_headers="s390intrin.h htmintrin.h htmxlintrin.h vecintrin.h"
target_gtfiles="./s390-gen-builtins.h"
@@ -625,6 +638,12 @@ then
rust_target_objs="${rust_target_objs} ${cpu_type}-rust.o"
fi
+tm_jit_file=
+if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-jit.h
+then
+ tm_jit_file="${tm_jit_file} ${cpu_type}/${cpu_type}-jit.h"
+fi
+
extra_modes=
if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-modes.def
then
@@ -792,11 +811,13 @@ case ${target} in
c_target_objs="${c_target_objs} darwin-c.o"
cxx_target_objs="${cxx_target_objs} darwin-c.o"
d_target_objs="${d_target_objs} darwin-d.o"
+ #jit_target_objs="${jit_target_objs} darwin-jit.o"
fortran_target_objs="darwin-f.o"
rust_target_objs="${rust_target_objs} darwin-rust.o"
target_has_targetcm=yes
target_has_targetdm=yes
target_has_targetrustm=yes
+ #target_has_targetjitm=yes
extra_objs="${extra_objs} darwin.o"
extra_gcc_objs="darwin-driver.o"
default_use_cxa_atexit=yes
@@ -825,10 +846,12 @@ case ${target} in
default_use_cxa_atexit=yes
use_gcc_stdint=wrap
d_target_objs="${d_target_objs} dragonfly-d.o"
+ #jit_target_objs="${jit_target_objs} dragonfly-jit.o"
tmake_file="${tmake_file} t-dragonfly"
target_has_targetdm=yes
rust_target_objs="${rust_target_objs} dragonfly-rust.o"
target_has_targetrustm=yes
+ #target_has_targetjitm=yes
;;
*-*-freebsd*)
# This is the generic ELF configuration of FreeBSD. Later
@@ -878,10 +901,12 @@ case ${target} in
esac
use_gcc_stdint=wrap
d_target_objs="${d_target_objs} freebsd-d.o"
+ #jit_target_objs="${jit_target_objs} freebsd-jit.o"
tmake_file="${tmake_file} t-freebsd"
target_has_targetdm=yes
rust_target_objs="${rust_target_objs} freebsd-rust.o"
target_has_targetrustm=yes
+ #target_has_targetjitm=yes
;;
*-*-fuchsia*)
native_system_header_dir=/include
@@ -957,21 +982,29 @@ case ${target} in
case $target in
*-*-*linux*)
d_target_objs="${d_target_objs} linux-d.o"
+ jit_target_objs="${jit_target_objs} linux-jit.o"
target_has_targetdm=yes
rust_target_objs="${rust_target_objs} linux-rust.o"
target_has_targetrustm=yes
+ target_has_targetjitm=yes
;;
*-*-kfreebsd*-gnu)
d_target_objs="${d_target_objs} kfreebsd-d.o"
+ #jit_target_objs="${jit_target_objs} kfreebsd-jit.o"
target_has_targetdm=yes
+ #target_has_targetjitm=yes
;;
*-*-kopensolaris*-gnu)
d_target_objs="${d_target_objs} kopensolaris-d.o"
+ #jit_target_objs="${jit_target_objs} kopensolaris-jit.o"
target_has_targetdm=yes
+ #target_has_targetjitm=yes
;;
*-*-gnu*)
d_target_objs="${d_target_objs} gnu-d.o"
+ #jit_target_objs="${jit_target_objs} gnu-jit.o"
target_has_targetdm=yes
+ #target_has_targetjitm=yes
;;
esac
;;
@@ -980,6 +1013,7 @@ case ${target} in
tmake_file="t-netbsd t-slibgcc"
extra_objs="${extra_objs} netbsd.o"
d_target_objs="${d_target_objs} netbsd-d.o"
+ #jit_target_objs="${jit_target_objs} netbsd-jit.o"
gas=yes
gnu_ld=yes
use_gcc_stdint=wrap
@@ -989,6 +1023,7 @@ case ${target} in
nbsd_tm_file="netbsd.h netbsd-stdint.h netbsd-elf.h"
default_use_cxa_atexit=yes
target_has_targetdm=yes
+ #target_has_targetjitm=yes
case ${target} in
arm*-* | i[34567]86-* | powerpc*-* | sparc*-* | x86_64-*)
default_gnu_indirect_function=yes
@@ -1010,9 +1045,11 @@ case ${target} in
;;
esac
d_target_objs="${d_target_objs} openbsd-d.o"
+ #jit_target_objs="${jit_target_objs} openbsd-jit.o"
target_has_targetdm=yes
rust_target_objs="${rust_target_objs} openbsd-rust.o"
target_has_targetrustm=yes
+ #target_has_targetjitm=yes
;;
*-*-phoenix*)
gas=yes
@@ -1065,6 +1102,7 @@ case ${target} in
c_target_objs="${c_target_objs} sol2-c.o"
cxx_target_objs="${cxx_target_objs} sol2-c.o sol2-cxx.o"
d_target_objs="${d_target_objs} sol2-d.o"
+ #jit_target_objs="${jit_target_objs} sol2-jit.o"
extra_objs="${extra_objs} sol2.o sol2-stubs.o"
extra_options="${extra_options} sol2.opt"
case ${enable_threads}:${have_pthread_h}:${have_thread_h} in
@@ -1075,6 +1113,7 @@ case ${target} in
target_has_targetdm=yes
rust_target_objs="${rust_target_objs} sol2-rust.o"
target_has_targetrustm=yes
+ #target_has_targetjitm=yes
;;
*-*-*vms*)
extra_options="${extra_options} vms/vms.opt"
@@ -1863,6 +1902,7 @@ hppa*64*-*-linux*)
pa/pa64-linux.h"
tmake_file="${tmake_file} pa/t-pa pa/t-linux"
d_target_objs="${d_target_objs} pa-d.o"
+ #jit_target_objs="${jit_target_objs} pa-jit.o"
gas=yes gnu_ld=yes
;;
hppa*-*-linux*)
@@ -1871,6 +1911,7 @@ hppa*-*-linux*)
pa/pa32-regs.h pa/pa32-linux.h"
tmake_file="${tmake_file} pa/t-pa pa/t-linux"
d_target_objs="${d_target_objs} pa-d.o"
+ #jit_target_objs="${jit_target_objs} pa-jit.o"
;;
hppa*-*-openbsd*)
target_cpu_default="MASK_PA_11"
@@ -1879,6 +1920,7 @@ hppa*-*-openbsd*)
extra_options="${extra_options} openbsd.opt"
tmake_file="pa/t-pa"
d_target_objs="${d_target_objs} pa-d.o"
+ #jit_target_objs="${jit_target_objs} pa-jit.o"
gas=yes
gnu_ld=yes
;;
@@ -1916,6 +1958,7 @@ hppa*64*-*-hpux11*)
pa/pa-hpux1010.opt pa/pa64-hpux.opt hpux11.opt"
tmake_file="pa/t-pa t-slibgcc"
d_target_objs="${d_target_objs} pa-d.o"
+ #jit_target_objs="${jit_target_objs} pa-jit.o"
case x${enable_threads} in
x | xyes | xposix )
thread_file=posix
@@ -2195,7 +2238,9 @@ i[34567]86-*-cygwin*)
c_target_objs="${c_target_objs} msformat-c.o"
cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
d_target_objs="${d_target_objs} cygwin-d.o"
+ #jit_target_objs="${jit_target_objs} cygwin-jit.o"
target_has_targetdm="yes"
+ #target_has_targetjitm=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
@@ -2216,7 +2261,9 @@ x86_64-*-cygwin*)
c_target_objs="${c_target_objs} msformat-c.o"
cxx_target_objs="${cxx_target_objs} winnt-cxx.o msformat-c.o"
d_target_objs="${d_target_objs} cygwin-d.o"
+ #jit_target_objs="${jit_target_objs} cygwin-jit.o"
target_has_targetdm="yes"
+ #target_has_targetjitm=yes
if test x$enable_threads = xyes; then
thread_file='posix'
fi
@@ -2230,10 +2277,12 @@ i[34567]86-*-mingw* | x86_64-*-mingw*)
c_target_objs="${c_target_objs} winnt-c.o"
cxx_target_objs="${cxx_target_objs} winnt-c.o"
d_target_objs="${d_target_objs} winnt-d.o"
+ #jit_target_objs="${jit_target_objs} winnt-jit.o"
target_has_targetcm="yes"
target_has_targetdm="yes"
rust_target_objs="${rust_target_objs} winnt-rust.o"
target_has_targetrustm="yes"
+ #target_has_targetjitm=yes
case ${target} in
x86_64-*-* | *-w64-*)
need_64bit_isa=yes
@@ -3721,6 +3770,10 @@ if [ "$target_has_targetrustm" = "no" ]; then
rust_target_objs="$rust_target_objs default-rust.o"
fi
+if [ "$target_has_targetjitm" = "no" ]; then
+ jit_target_objs="$jit_target_objs default-jit.o"
+fi
+
# Support for --with-cpu and related options (and a few unrelated options,
# too).
case ${with_cpu} in
@@ -6022,6 +6075,7 @@ case ${target} in
c_target_objs="${c_target_objs} ${cpu_type}-c.o"
cxx_target_objs="${cxx_target_objs} ${cpu_type}-c.o"
d_target_objs="${d_target_objs} ${cpu_type}-d.o"
+ jit_target_objs="${jit_target_objs} ${cpu_type}-jit.o"
tmake_file="${cpu_type}/t-${cpu_type} ${tmake_file}"
;;
diff --git a/gcc/config/default-jit.cc b/gcc/config/default-jit.cc
new file mode 100644
index 0000000000000..1c4e23b43a286
--- /dev/null
+++ b/gcc/config/default-jit.cc
@@ -0,0 +1,29 @@
+/* Default JIT language target hooks initializer.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Do not include tm.h or tm_p.h here; definitions needed by the target
+ architecture to initialize targetjitm should instead be added to tm_jit.h.
+ */
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/i386/i386-jit.cc b/gcc/config/i386/i386-jit.cc
new file mode 100644
index 0000000000000..6a60764d74f35
--- /dev/null
+++ b/gcc/config/i386/i386-jit.cc
@@ -0,0 +1,64 @@
+/* Subroutines for the JIT front end on the x86 architecture.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#define IN_TARGET_CODE 1
+
+#define INCLUDE_STRING
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+/* Implement TARGET_JIT_REGISTER_CPU_TARGET_INFO. */
+
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+
+#if TARGET_64BIT_DEFAULT
+const char* x86_bits = "64";
+#else
+const char* x86_bits = "32";
+#endif
+
+void
+ix86_jit_register_target_info (void)
+{
+ const char *params[] = {"arch", x86_bits};
+ const char* local_cpu = host_detect_local_cpu (2, params);
+ std::string arch = local_cpu;
+ free (const_cast (local_cpu));
+
+ const char* arg = "-march=";
+ size_t arg_pos = arch.find (arg) + strlen (arg);
+ size_t end_pos = arch.find (" ", arg_pos);
+
+ std::string cpu = arch.substr (arg_pos, end_pos - arg_pos);
+ jit_target_set_arch (cpu);
+
+ if (targetm.scalar_mode_supported_p (TImode))
+ {
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_UINT128_T);
+ jit_target_add_supported_target_dependent_type (GCC_JIT_TYPE_INT128_T);
+ }
+
+#define ADD_TARGET_INFO jit_add_target_info
+#include "i386-rust-and-jit.inc"
+#undef ADD_TARGET_INFO
+}
diff --git a/gcc/config/i386/i386-jit.h b/gcc/config/i386/i386-jit.h
new file mode 100644
index 0000000000000..4f05e88003f7f
--- /dev/null
+++ b/gcc/config/i386/i386-jit.h
@@ -0,0 +1,22 @@
+/* Definitions for the jit front end on the x86 architecture.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+/* In i386-jit.cc */
+extern void ix86_jit_register_target_info (void);
+
+/* Target hooks for jit language. */
+#define TARGET_JIT_REGISTER_CPU_TARGET_INFO ix86_jit_register_target_info
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index bf4ae109af986..3452193c45fbd 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -50,6 +50,10 @@ i386-rust.o: $(srcdir)/config/i386/i386-rust.cc
$(COMPILE) $<
$(POSTCOMPILE)
+i386-jit.o: $(srcdir)/config/i386/i386-jit.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
+
i386-options.o: $(srcdir)/config/i386/i386-options.cc
$(COMPILE) $<
$(POSTCOMPILE)
diff --git a/gcc/config/linux-jit.cc b/gcc/config/linux-jit.cc
new file mode 100644
index 0000000000000..fe9b631110516
--- /dev/null
+++ b/gcc/config/linux-jit.cc
@@ -0,0 +1,38 @@
+/* Linux support needed only by jit front-end.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#define INCLUDE_STRING
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_jit.h"
+#include "jit/jit-target.h"
+#include "jit/jit-target-def.h"
+
+// TODO: remove this hook?
+/* Implement TARGET_JIT_REGISTER_OS_TARGET_INFO for Linux targets. */
+
+static void
+linux_jit_register_target_info (void)
+{
+}
+
+#undef TARGET_JIT_REGISTER_OS_TARGET_INFO
+#define TARGET_JIT_REGISTER_OS_TARGET_INFO linux_jit_register_target_info
+
+struct gcc_targetjitm targetjitm = TARGETJITM_INITIALIZER;
diff --git a/gcc/config/t-linux b/gcc/config/t-linux
index 5c5bfc5ca832a..dd705361068ce 100644
--- a/gcc/config/t-linux
+++ b/gcc/config/t-linux
@@ -27,3 +27,7 @@ linux-d.o: $(srcdir)/config/linux-d.cc
linux-rust.o: $(srcdir)/config/linux-rust.cc
$(COMPILE) $<
$(POSTCOMPILE)
+
+linux-jit.o: $(srcdir)/config/linux-jit.cc
+ $(COMPILE) $<
+ $(POSTCOMPILE)
diff --git a/gcc/configure b/gcc/configure
index 5acc42c1e4d93..9478be31dec6c 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -648,6 +648,7 @@ GMPLIBS
target_cpu_default
rust_target_objs
d_target_objs
+jit_target_objs
fortran_target_objs
cxx_target_objs
c_target_objs
@@ -659,6 +660,8 @@ tm_rust_include_list
tm_rust_file_list
tm_d_include_list
tm_d_file_list
+tm_jit_include_list
+tm_jit_file_list
tm_p_include_list
tm_p_file_list
tm_defines
@@ -15034,6 +15037,17 @@ for f in $tm_rust_file; do
esac
done
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+ case $f in
+ * )
+ tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+ tm_jit_include_list="${tm_jit_include_list} config/$f"
+ ;;
+ esac
+done
+
xm_file_list=
xm_include_list=
for f in $xm_file; do
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 23f4884eff9e4..131c3a23584b6 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2423,6 +2423,17 @@ for f in $tm_rust_file; do
esac
done
+tm_jit_file_list=
+tm_jit_include_list=
+for f in $tm_jit_file; do
+ case $f in
+ * )
+ tm_jit_file_list="${tm_jit_file_list} \$(srcdir)/config/$f"
+ tm_jit_include_list="${tm_jit_include_list} config/$f"
+ ;;
+ esac
+done
+
xm_file_list=
xm_include_list=
for f in $xm_file; do
@@ -7542,6 +7553,8 @@ AC_SUBST(tm_d_file_list)
AC_SUBST(tm_d_include_list)
AC_SUBST(tm_rust_file_list)
AC_SUBST(tm_rust_include_list)
+AC_SUBST(tm_jit_file_list)
+AC_SUBST(tm_jit_include_list)
AC_SUBST(xm_file_list)
AC_SUBST(xm_include_list)
AC_SUBST(xm_defines)
@@ -7551,6 +7564,7 @@ AC_SUBST(cxx_target_objs)
AC_SUBST(fortran_target_objs)
AC_SUBST(d_target_objs)
AC_SUBST(rust_target_objs)
+AC_SUBST(jit_target_objs)
AC_SUBST(target_cpu_default)
AC_SUBST_FILE(language_hooks)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 4deb3d2c283a2..30c9f6dbbf4ea 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
@code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
default definition is used.
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}. If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
@node Driver
@section Controlling the Compilation Driver, @file{gcc}
@cindex driver
@@ -11260,6 +11268,24 @@ Similar to @code{TARGET_RUST_CPU_INFO}, but is used for configuration info
relating to the target operating system.
@end deftypefn
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@deftypefn {JIT Target Hook} void TARGET_JIT_REGISTER_CPU_TARGET_INFO (void)
+Register all target information keys relating to the target CPU using the
+function @code{jit_add_target_info_handlers}, which takes a
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-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 {JIT Target Hook} void TARGET_JIT_REGISTER_OS_TARGET_INFO (void)
+Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to
+the target operating system.
+@end deftypefn
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 9f147ccb95cc6..5d24844799c79 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -124,6 +124,14 @@ If targets initialize @code{targetrustm} themselves, they should set
@code{target_has_targetrustm=yes} in @file{config.gcc}; otherwise a
default definition is used.
+Similarly, there is a @code{targetjitm} variable for hooks that are
+specific to the jit front end, documented as ``JIT Target Hook''.
+This is declared in @file{jit/jit-target.h}, the initializer
+@code{TARGETJITM_INITIALIZER} in @file{jit/jit-target-def.h}. If targets
+initialize @code{targetjitm} themselves, they should set
+@code{target_has_targetjitm=yes} in @file{config.gcc}; otherwise a default
+definition is used.
+
@node Driver
@section Controlling the Compilation Driver, @file{gcc}
@cindex driver
@@ -7263,6 +7271,14 @@ floating-point support; they are not included in this mechanism.
@hook TARGET_RUST_OS_INFO
+@node JIT Language and ABI
+@section JIT ABI parameters
+@cindex parameters, jit abi
+
+@hook TARGET_JIT_REGISTER_CPU_TARGET_INFO
+
+@hook TARGET_JIT_REGISTER_OS_TARGET_INFO
+
@node Named Address Spaces
@section Adding support for named address spaces
@cindex named address spaces
diff --git a/gcc/genhooks.cc b/gcc/genhooks.cc
index 8a55ad184d67d..b5898f471fae9 100644
--- a/gcc/genhooks.cc
+++ b/gcc/genhooks.cc
@@ -36,6 +36,7 @@ static struct hook_desc hook_array[] = {
#include "common/common-target.def"
#include "d/d-target.def"
#include "rust/rust-target.def"
+#include "jit/jit-target.def"
#undef DEFHOOK
};
diff --git a/gcc/jit/Make-lang.in b/gcc/jit/Make-lang.in
index 99b3d549d5d45..c2aa6bd8e28b9 100644
--- a/gcc/jit/Make-lang.in
+++ b/gcc/jit/Make-lang.in
@@ -130,7 +130,7 @@ jit.serial = $(LIBGCCJIT_FILENAME)
# Tell GNU make to ignore these if they exist.
.PHONY: jit
-jit_OBJS = attribs.o \
+JIT_OBJS = attribs.o \
jit/dummy-frontend.o \
jit/libgccjit.o \
jit/jit-logging.o \
@@ -139,13 +139,17 @@ jit_OBJS = attribs.o \
jit/jit-result.o \
jit/jit-tempdir.o \
jit/jit-builtins.o \
+ jit/jit-target.o \
jit/jit-spec.o \
gcc.o
ifneq (,$(findstring mingw,$(target)))
-jit_OBJS += jit/jit-w32.o
+JIT_OBJS += jit/jit-w32.o
endif
+# All language-specific object files for jit.
+jit_OBJS = $(JIT_OBJS) $(JIT_TARGET_OBJS)
+
# Use strict warnings for this front end.
jit-warn = $(STRICT_WARN)
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index 92c3ed24c892e..723cac83e349c 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -404,3 +404,16 @@ on functions and variables:
--------------------
``LIBGCCJIT_ABI_28`` covers the addition of
:func:`gcc_jit_context_new_alignof`
+
+.. _LIBGCCJIT_ABI_29:
+
+``LIBGCCJIT_ABI_29``
+--------------------
+``LIBGCCJIT_ABI_29`` covers the addition of functions to query the target
+information:
+
+ * :func:`gcc_jit_context_get_target_info`
+ * :func:`gcc_jit_target_info_release`
+ * :func:`gcc_jit_target_info_cpu_supports`
+ * :func:`gcc_jit_target_info_arch`
+ * :func:`gcc_jit_target_info_supports_target_dependent_type`
diff --git a/gcc/jit/docs/topics/compilation.rst b/gcc/jit/docs/topics/compilation.rst
index 5891bf0dc698e..5830e6184b47c 100644
--- a/gcc/jit/docs/topics/compilation.rst
+++ b/gcc/jit/docs/topics/compilation.rst
@@ -199,3 +199,55 @@ The available kinds of output are:
.. c:macro:: GCC_JIT_OUTPUT_KIND_EXECUTABLE
Compile the context to an executable.
+
+Getting information about a target
+**********************************
+
+You can query the target information by using the following API:
+
+.. function:: gcc_jit_target_info * \
+ gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+
+ Compute the information about a target.
+
+ If the result is non-NULL, the caller becomes responsible for
+ calling :func:`gcc_jit_target_info_release` on it once they're done
+ with it.
+
+.. function:: void \
+ gcc_jit_target_info_release (gcc_jit_target_info *info)
+
+ This function releases all resources associated with the given target info.
+
+.. function:: int \
+ gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+ const char *feature)
+
+ Check if the specified target INFO supports the cpu FEATURE.
+
+.. function:: const char * \
+ gcc_jit_target_info_arch (gcc_jit_target_info *info)
+
+ Get the architecture of the currently running CPU.
+
+.. function:: int \
+ gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info,
+ enum gcc_jit_types type)
+
+ Check if the specified target INFO supports target-dependent types like
+ 128-bit integers.
+
+ The API entrypoints relating to the target info:
+
+ * :c:func:`gcc_jit_context_get_target_info`
+ * :c:func:`gcc_jit_target_info_release`
+ * :c:func:`gcc_jit_target_info_cpu_supports`
+ * :c:func:`gcc_jit_target_info_arch`
+ * :c:func:`gcc_jit_target_info_supports_target_dependent_type`
+
+ were added in :ref:`LIBGCCJIT_ABI_29`; you can test for their presence
+ using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
diff --git a/gcc/jit/jit-playback.cc b/gcc/jit/jit-playback.cc
index 583956fb4635d..3027217369b52 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "jit-result.h"
#include "jit-builtins.h"
#include "jit-tempdir.h"
+#include "jit-target.h"
#ifdef _WIN32
#include "jit-w32.h"
@@ -3400,6 +3401,7 @@ replay ()
JIT_LOG_SCOPE (get_logger ());
init_types ();
+ jit_target_init ();
/* Replay the recorded events: */
timevar_push (TV_JIT_REPLAY);
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 6e97b389cbb0d..a840392c79e3f 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -54,9 +54,10 @@ set_variable_string_attribute (
/* playback::context is an abstract base class.
- The two concrete subclasses are:
+ The three concrete subclasses are:
- playback::compile_to_memory
- - playback::compile_to_file. */
+ - playback::compile_to_file.
+ - playback::get_target_info */
class context : public log_user
{
@@ -436,6 +437,18 @@ class compile_to_file : public context
const char *m_output_path;
};
+class get_target_info : public context
+{
+ public:
+ get_target_info (recording::context *ctxt) : context (ctxt)
+ {
+ }
+
+ void postprocess (const char *) final override
+ {
+ }
+};
+
/* A temporary wrapper object.
These objects are (mostly) only valid during replay.
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index cc7f529c9e8a0..fcf4661fcd0b4 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1556,6 +1556,25 @@ recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
replayer.compile ();
}
+void
+recording::context::get_target_info ()
+{
+ JIT_LOG_SCOPE (get_logger ());
+
+ log_all_options ();
+
+ if (errors_occurred ())
+ return;
+
+ add_driver_option ("-fsyntax-only");
+
+ /* Set up a get_target_info playback context. */
+ ::gcc::jit::playback::get_target_info replayer (this);
+
+ /* Use it. */
+ replayer.compile ();
+}
+
/* Format the given error using printf's conventions, print
it to stderr, and add it to the context. */
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index abd4f6f8bb334..ec296d7b63062 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -298,6 +298,9 @@ class context : public log_user
compile_to_file (enum gcc_jit_output_kind output_kind,
const char *output_path);
+ void
+ get_target_info ();
+
void
add_error (location *loc, const char *fmt, ...)
GNU_PRINTF(3, 4);
diff --git a/gcc/jit/jit-target-def.h b/gcc/jit/jit-target-def.h
new file mode 100644
index 0000000000000..dcb342fafe7d6
--- /dev/null
+++ b/gcc/jit/jit-target-def.h
@@ -0,0 +1,20 @@
+/* jit-target-def.h -- Default initializers for jit target hooks.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not see
+ . */
+
+#include "jit/jit-target-hooks-def.h"
+#include "tree.h"
+#include "hooks.h"
diff --git a/gcc/jit/jit-target.cc b/gcc/jit/jit-target.cc
new file mode 100644
index 0000000000000..d37144350cc05
--- /dev/null
+++ b/gcc/jit/jit-target.cc
@@ -0,0 +1,89 @@
+/* jit-target.cc -- Target interface for the jit front end.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+. */
+
+#define INCLUDE_STRING
+#define INCLUDE_ALGORITHM
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+
+#include "tree.h"
+#include "memmodel.h"
+#include "fold-const.h"
+#include "diagnostic.h"
+#include "stor-layout.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "target.h"
+#include "calls.h"
+
+#include "jit-target.h"
+
+static target_info jit_target_info;
+
+/* Initialize all variables of the Target structure. */
+
+void
+jit_target_init ()
+{
+ /* Initialize target info tables, the keys required by the language are added
+ last, so that the OS and CPU handlers can override. */
+ targetjitm.jit_register_cpu_target_info ();
+ targetjitm.jit_register_os_target_info ();
+}
+
+/* Add a target info key:value to JIT_TARGET_INFO for use by
+ target_info::has_target_value (). */
+
+void
+jit_add_target_info (const char *key, const char *value)
+{
+ if (jit_target_info.m_info.find (key) == jit_target_info.m_info.end ())
+ jit_target_info.m_info.insert ({key, {value}});
+ else
+ jit_target_info.m_info[key].insert (value);
+}
+
+void
+jit_target_set_arch (std::string const& arch)
+{
+ jit_target_info.m_arch = arch;
+}
+
+void
+jit_target_add_supported_target_dependent_type (enum gcc_jit_types type_)
+{
+ jit_target_info.m_supported_target_dependent_types.insert (type_);
+}
+
+target_info *
+jit_get_target_info ()
+{
+ target_info *info = new target_info {jit_target_info};
+ jit_target_info = target_info{};
+ return info;
+}
+
+bool
+target_info::has_target_value (const char *key, const char *value)
+{
+ if (m_info.find (key) == m_info.end ())
+ return false;
+
+ auto& set = m_info[key];
+ return set.find (value) != set.end ();
+}
diff --git a/gcc/jit/jit-target.def b/gcc/jit/jit-target.def
new file mode 100644
index 0000000000000..de0d717b365d1
--- /dev/null
+++ b/gcc/jit/jit-target.def
@@ -0,0 +1,52 @@
+/* jit-target.def -- Target hook definitions for the jit front end.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not see
+ . */
+
+/* See target-hooks-macros.h for details of macros that should be
+ provided by the including file, and how to use them here. */
+
+#include "target-hooks-macros.h"
+
+#undef HOOK_TYPE
+#define HOOK_TYPE "JIT Target Hook"
+
+HOOK_VECTOR (TARGETJITM_INITIALIZER, gcc_targetjitm)
+
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_"
+
+/* getTargetInfo keys relating to the target CPU. */
+DEFHOOK
+(jit_register_cpu_target_info,
+ "Register all target information keys relating to the target CPU using the\n\
+function @code{jit_add_target_info_handlers}, which takes a\n\
+@samp{struct jit_target_info_spec} (defined in @file{jit/jit-target.h}). The\n\
+keys 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
+(jit_register_os_target_info,
+ "Same as @code{TARGET_JIT_CPU_TARGET_INFO}, but is used for keys relating to\n\
+the target operating system.",
+ void, (void),
+ hook_void_void)
+
+/* Close the 'struct gcc_targetdm' definition. */
+HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/jit/jit-target.h b/gcc/jit/jit-target.h
new file mode 100644
index 0000000000000..e8a20182c3844
--- /dev/null
+++ b/gcc/jit/jit-target.h
@@ -0,0 +1,75 @@
+/* jit-target.h -- Data structure definitions for target-specific jit behavior.
+ Copyright (C) 2023 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING3. If not see
+ . */
+
+#ifndef GCC_JIT_TARGET_H
+#define GCC_JIT_TARGET_H
+
+#define DEFHOOKPOD(NAME, DOC, TYPE, INIT) TYPE NAME;
+#define DEFHOOK(NAME, DOC, TYPE, PARAMS, INIT) TYPE (* NAME) PARAMS;
+#define DEFHOOK_UNDOC DEFHOOK
+#define HOOKSTRUCT(FRAGMENT) FRAGMENT
+
+#include "jit-target.def"
+#include "libgccjit.h"
+
+#include
+#include
+
+static size_t hash_cstr (const char *s)
+{
+ const size_t seed = 0;
+ return std::_Hash_bytes (s, std::strlen (s), seed);
+}
+
+struct CStringHash {
+ size_t operator() (const char* const &string) const {
+ auto res = hash_cstr (string);
+ return res;
+ }
+};
+
+struct CStringEqual {
+ bool
+ operator() (const char *const &string1, const char *const &string2) const
+ {
+ return strcmp (string1, string2) == 0;
+ }
+};
+
+struct target_info {
+ public:
+ bool has_target_value (const char *key, const char *value);
+
+ std::unordered_map,
+ CStringHash, CStringEqual>
+ m_info;
+ std::string m_arch;
+ std::unordered_set m_supported_target_dependent_types;
+};
+
+/* Each target can provide their own. */
+extern struct gcc_targetjitm targetjitm;
+
+extern void jit_target_init ();
+extern void jit_target_set_arch (std::string const& arch);
+extern void
+jit_target_add_supported_target_dependent_type (enum gcc_jit_types type_);
+extern void jit_add_target_info (const char *key, const char *value);
+extern target_info * jit_get_target_info ();
+
+#endif /* GCC_JIT_TARGET_H */
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index eb38da91df1ec..e78e18c31e691 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "libgccjit.h"
#include "jit-recording.h"
#include "jit-result.h"
+#include "jit-target.h"
/* The opaque types used by the public API are actually subclasses
of the gcc::jit::recording classes. */
@@ -44,6 +45,10 @@ struct gcc_jit_result : public gcc::jit::result
{
};
+struct gcc_jit_target_info : public target_info
+{
+};
+
struct gcc_jit_object : public gcc::jit::recording::memento
{
};
@@ -3715,6 +3720,50 @@ gcc_jit_context_compile_to_file (gcc_jit_context *ctxt,
ctxt->compile_to_file (output_kind, output_path);
}
+gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt)
+{
+ RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context");
+ JIT_LOG_FUNC (ctxt->get_logger ());
+
+ ctxt->log ("get_target_info of ctxt: %p", (void *)ctxt);
+
+ ctxt->get_target_info ();
+
+ return (gcc_jit_target_info*) jit_get_target_info ();
+}
+
+void
+gcc_jit_target_info_release (gcc_jit_target_info *info)
+{
+ RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+ delete info;
+}
+
+int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+ const char *feature)
+{
+ RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+ RETURN_NULL_IF_FAIL (feature, ctxt, loc, "NULL feature");
+ return info->has_target_value ("target_feature", feature);
+}
+
+const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info)
+{
+ RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+ return info->m_arch.c_str ();
+}
+
+int
+gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info,
+ enum gcc_jit_types type)
+{
+ RETURN_IF_FAIL (info, NULL, NULL, "NULL info");
+ return info->m_supported_target_dependent_types.find (type)
+ != info->m_supported_target_dependent_types.end ();
+}
/* Public entrypoint. See description in libgccjit.h.
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index 03bfc0f58a533..a50bd70652ac1 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -57,6 +57,9 @@ typedef struct gcc_jit_context gcc_jit_context;
/* A gcc_jit_result encapsulates the result of an in-memory compilation. */
typedef struct gcc_jit_result gcc_jit_result;
+/* A gcc_jit_target_info encapsulates the target info. */
+typedef struct gcc_jit_target_info gcc_jit_target_info;
+
/* An object created within a context. Such objects are automatically
cleaned up when the context is released.
@@ -2064,6 +2067,60 @@ gcc_jit_function_add_string_attribute (gcc_jit_function *func,
enum gcc_jit_fn_attribute attribute,
const char* value);
+/* Create a gcc_jit_target_info instance.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+extern gcc_jit_target_info *
+gcc_jit_context_get_target_info (gcc_jit_context *ctxt);
+
+/* Release a gcc_jit_target_info instance.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+extern void
+gcc_jit_target_info_release (gcc_jit_target_info *info);
+
+/* Returns non-zero if FEATURE is supported by the specified target.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+extern int
+gcc_jit_target_info_cpu_supports (gcc_jit_target_info *info,
+ const char *feature);
+
+/* Returns the ARCH of the currently running CPU.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+extern const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info);
+
+/* Returns non-zero if the target natively supports the target-dependent type
+ TYPE.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+extern int
+gcc_jit_target_info_supports_target_dependent_type (gcc_jit_target_info *info,
+ enum gcc_jit_types type);
+
+/* The target info API was added in LIBGCCJIT_ABI_29; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_TARGET_INFO_API
+*/
+#define LIBGCCJIT_HAVE_TARGET_INFO_API
+
extern void
gcc_jit_function_add_integer_array_attribute (
gcc_jit_function *func,
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index b02783ebfb24d..988cfbf6fdd7f 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -294,3 +294,12 @@ LIBGCCJIT_ABI_28 {
global:
gcc_jit_context_new_alignof;
} LIBGCCJIT_ABI_27;
+
+LIBGCCJIT_ABI_29 {
+ global:
+ gcc_jit_context_get_target_info;
+ gcc_jit_target_info_release;
+ gcc_jit_target_info_cpu_supports;
+ gcc_jit_target_info_arch;
+ gcc_jit_target_info_supports_target_dependent_type;
+} LIBGCCJIT_ABI_28;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 75721329ab531..c75e9a532eb03 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -391,6 +391,9 @@
#undef create_code
#undef verify_code
+/* test-target-info.c: This can't be in the testcases array as it
+ is target-specific. */
+
/* test-types.c */
#define create_code create_code_types
#define verify_code verify_code_types
diff --git a/gcc/testsuite/jit.dg/test-target-info.c b/gcc/testsuite/jit.dg/test-target-info.c
new file mode 100644
index 0000000000000..32c0766f1ed4e
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-info.c
@@ -0,0 +1,65 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include
+#include
+
+#include "libgccjit.h"
+
+#define TEST_PROVIDES_MAIN
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+}
+
+int
+main (int argc, char **argv)
+{
+ /* This is the same as the main provided by harness.h, but calls gcc_jit_context_get_target_info. */
+ gcc_jit_context *ctxt;
+ ctxt = gcc_jit_context_acquire ();
+ if (!ctxt)
+ {
+ fail ("gcc_jit_context_acquire failed");
+ return -1;
+ }
+ gcc_jit_target_info* info = gcc_jit_context_get_target_info (ctxt);
+
+ int sse2_supported = gcc_jit_target_info_cpu_supports (info, "sse2");
+ CHECK_VALUE (sse2_supported, 1);
+
+ const char *arch = gcc_jit_target_info_arch (info);
+ // TODO: not sure what value to check here.
+ CHECK_STRING_VALUE (arch, "znver2");
+
+ int supports_128bit_int =
+ gcc_jit_target_info_supports_target_dependent_type (info,
+ GCC_JIT_TYPE_INT128_T);
+ CHECK_VALUE (supports_128bit_int, 1);
+ gcc_jit_target_info_release (info);
+ gcc_jit_context_release (ctxt);
+
+ int i;
+
+ for (i = 1; i <= 5; i++)
+ {
+ snprintf (test, sizeof (test),
+ "%s iteration %d of %d",
+ extract_progname (argv[0]),
+ i, 5);
+
+ //printf ("ITERATION %d\n", i);
+ test_jit (argv[0], NULL);
+ //printf ("\n");
+ }
+
+ totals ();
+
+ return 0;
+}