https://gcc.gnu.org/g:2a54db2d8baa1de9d552dfd561849f59737c062f

commit r16-4279-g2a54db2d8baa1de9d552dfd561849f59737c062f
Author: Antoni Boucher <[email protected]>
Date:   Fri Mar 21 13:13:41 2025 -0400

    libgccjit: Add ability to get CPU features
    
    gcc/ChangeLog:
            PR jit/112466
            * Makefile.in (tm_jit_file_list, tm_jit_include_list, TM_JIT_H,
            JIT_TARGET_DEF, JIT_TARGET_H, JIT_TARGET_OBJS): New variables.
            (tm_jit.h, cs-tm_jit.h, jit/jit-target-hooks-def.h,
            s-jit-target-hooks-def-h, default-jit.o): New rules.
            (s-tm-texi): Also check timestamp on jit-target.def.
            (generated_files): Add TM_JIT_H and jit/jit-target-hooks-def.h.
            (build/genhooks.o): Also depend on JIT_TARGET_DEF.
            * config.gcc (tm_jit_file, jit_target_objs, target_has_targetjitm):
            New variables.
            * config/i386/t-i386 (i386-jit.o): New rule.
            * configure: Regenerate.
            * configure.ac (tm_jit_file_list, tm_jit_include_list,
            jit_target_objs): Add substitutes.
            * doc/tm.texi: Regenerate.
            * doc/tm.texi.in (targetjitm): Document.
            (target_has_targetjitm): Document.
            * genhooks.cc: Include jit/jit-target.def.
            * config/default-jit.cc: New file.
            * config/i386/i386-jit.cc: New file.
            * config/i386/i386-jit.h: New file.
    
    gcc/jit/ChangeLog:
            PR jit/112466
            * Make-lang.in (JIT_OBJS): New variable.
            * jit-playback.cc (replay): Include jit-target.h and initialize
            target.
            * jit-playback.h (class populate_target_info): New class.
            * jit-recording.cc (recording::context::populate_target_info): New
            method.
            * jit-recording.h (recording::context::populate_target_info): New
            method.
            (recording::context::m_populated_target_info): New field.
            * libgccjit.cc: Include jit-target.h.
            (struct gcc_jit_target_info): New struct.
            (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): New functions.
            * libgccjit.h (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):
            New functions.
            * libgccjit.map (LIBGCCJIT_ABI_35): New ABI tag.
            * docs/topics/compilation.rst: Add documentation for the
            functions 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.
            * docs/topics/compatibility.rst (LIBGCCJIT_ABI_35): New ABI tag.
            * jit-target-def.h: New file.
            * jit-target.cc: New file.
            * jit-target.def: New file.
            * jit-target.h: New file.
    
    gcc/testsuite/ChangeLog:
            PR jit/112466
            * jit.dg/all-non-failing-tests.h: Mention
            test-target-info.c.
            * jit.dg/test-target-info.c: New test.
            * jit.dg/test-error-target-info.c: New test.

Diff:
---
 gcc/Makefile.in                               | 38 +++++++++--
 gcc/config.gcc                                | 20 ++++++
 gcc/config/default-jit.cc                     | 30 +++++++++
 gcc/config/i386/i386-jit.cc                   | 71 ++++++++++++++++++++
 gcc/config/i386/i386-jit.h                    | 22 ++++++
 gcc/config/i386/t-i386                        |  4 ++
 gcc/configure                                 | 14 ++++
 gcc/configure.ac                              | 14 ++++
 gcc/doc/tm.texi                               | 19 ++++++
 gcc/doc/tm.texi.in                            | 14 ++++
 gcc/genhooks.cc                               |  1 +
 gcc/jit/Make-lang.in                          |  8 ++-
 gcc/jit/docs/topics/compatibility.rst         | 13 ++++
 gcc/jit/docs/topics/compilation.rst           | 56 ++++++++++++++++
 gcc/jit/jit-playback.cc                       |  2 +
 gcc/jit/jit-playback.h                        | 32 ++++++++-
 gcc/jit/jit-recording.cc                      | 36 ++++++++++
 gcc/jit/jit-recording.h                       | 15 +++++
 gcc/jit/jit-target-def.h                      | 20 ++++++
 gcc/jit/jit-target.cc                         | 96 +++++++++++++++++++++++++++
 gcc/jit/jit-target.def                        | 42 ++++++++++++
 gcc/jit/jit-target.h                          | 75 +++++++++++++++++++++
 gcc/jit/libgccjit.cc                          | 51 ++++++++++++++
 gcc/jit/libgccjit.h                           | 57 ++++++++++++++++
 gcc/jit/libgccjit.map                         |  9 +++
 gcc/testsuite/jit.dg/all-non-failing-tests.h  |  3 +
 gcc/testsuite/jit.dg/test-error-target-info.c | 60 +++++++++++++++++
 gcc/testsuite/jit.dg/test-target-info.c       | 61 +++++++++++++++++
 28 files changed, 875 insertions(+), 8 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6a9d6204c869..e36e04a62eab 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -613,6 +613,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@
@@ -917,6 +919,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)
 
@@ -977,11 +980,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)
@@ -1297,6 +1302,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@
 
@@ -2105,6 +2113,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="" \
@@ -2144,6 +2153,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
@@ -2611,6 +2625,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
@@ -2963,6 +2983,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
@@ -3160,8 +3189,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 \
@@ -3172,6 +3201,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
 
 #
@@ -3305,8 +3335,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 9c8f4d05330b..a73bf9578e91 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 targetjitm.
 
 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.
@@ -416,6 +424,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"
@@ -620,6 +629,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
@@ -3714,6 +3729,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
@@ -6087,6 +6106,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 000000000000..a03308ef6dab
--- /dev/null
+++ b/gcc/config/default-jit.cc
@@ -0,0 +1,30 @@
+/* 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
+<http://www.gnu.org/licenses/>.  */
+
+#define INCLUDE_STRING
+#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 000000000000..c1e2929a4735
--- /dev/null
+++ b/gcc/config/i386/i386-jit.cc
@@ -0,0 +1,71 @@
+/* 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
+<http://www.gnu.org/licenses/>.  */
+
+#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.  */
+
+#ifndef CROSS_DIRECTORY_STRUCTURE
+extern const char *host_detect_local_cpu (int argc, const char **argv);
+#endif
+
+#if TARGET_64BIT_DEFAULT
+const char* x86_bits = "64";
+#else
+const char* x86_bits = "32";
+#endif
+
+void
+ix86_jit_register_target_info (void)
+{
+#ifndef CROSS_DIRECTORY_STRUCTURE
+  const char *params[] = {"arch", x86_bits};
+  const char* local_cpu = host_detect_local_cpu (2, params);
+  if (local_cpu)
+  {
+    std::string arch = local_cpu;
+    free (const_cast <char *> (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);
+  }
+#endif
+
+  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 000000000000..1d65001476ee
--- /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
+<http://www.gnu.org/licenses/>.  */
+
+/* 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 2508f89cd06a..e5fc929c1fec 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/configure b/gcc/configure
index 38d8cd919cba..0fb09f430da6 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -651,6 +651,7 @@ GMPLIBS
 target_cpu_default
 rust_target_objs
 d_target_objs
+jit_target_objs
 fortran_target_objs
 cxx_target_objs
 c_target_objs
@@ -662,6 +663,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
@@ -15114,6 +15117,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 19975fa5be5b..684639d4cafd 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2443,6 +2443,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
@@ -7596,6 +7607,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)
@@ -7605,6 +7618,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 0d109391f0b1..6012cd93680d 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -126,6 +126,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
@@ -11396,6 +11404,17 @@ 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}, which takes a key and a value.  The
+keys added by this hook are made available at compile time by calling
+get_target_info.
+@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 b28519081587..7fcd2ff99890 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -126,6 +126,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
@@ -7302,6 +7310,12 @@ 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
+
 @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 b984bee69ea8..529417b50f22 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 59afe264a856..0429137d694d 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 1c4b81bfff1a..19be33eb4b50 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -453,3 +453,16 @@ temporary variable:
 ``LIBGCCJIT_ABI_34`` covers the addition of
 
  * :func:`gcc_jit_context_set_output_ident`
+
+.. _LIBGCCJIT_ABI_35:
+
+``LIBGCCJIT_ABI_35``
+--------------------
+``LIBGCCJIT_ABI_35`` 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 3d3a9ab4db33..80c80af510d2 100644
--- a/gcc/jit/docs/topics/compilation.rst
+++ b/gcc/jit/docs/topics/compilation.rst
@@ -199,3 +199,59 @@ 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, e.g. the value of -march
+   equivalent to -march=native. Ex.: znver3
+
+   The underlying buffer is only valid until the gcc_jit_target_info is
+   released.
+
+.. 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_35`; 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 4473d8b55521..291ddeb2cca2 100644
--- a/gcc/jit/jit-playback.cc
+++ b/gcc/jit/jit-playback.cc
@@ -50,6 +50,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"
@@ -3605,6 +3606,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 b0625dca71f1..07dab6fa3895 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "varasm.h"
 
 #include "jit-recording.h"
+#include "jit-target.h"
 
 namespace diagnostics
 {
@@ -57,9 +58,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::populate_target_info  */
 
 class context : public log_user
 {
@@ -326,6 +328,18 @@ public:
 
   void add_top_level_asm (const char *asm_stmts);
 
+  target_info *get_target_info ()
+  {
+      return &m_target_info;
+  }
+
+  target_info *move_target_info ()
+  {
+    target_info *info = new target_info {std::move (m_target_info)};
+    m_target_info = target_info{};
+    return info;
+  }
+
 private:
   void dump_generated_code ();
 
@@ -429,6 +443,8 @@ private:
   auto_vec<source_file *> m_source_files;
 
   auto_vec<std::pair<tree, location *> > m_cached_locations;
+
+  target_info m_target_info;
 };
 
 class compile_to_memory : public context
@@ -461,6 +477,18 @@ class compile_to_file : public context
   const char *m_output_path;
 };
 
+class populate_target_info : public context
+{
+ public:
+  populate_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 8da3cb059156..2f4ecc318251 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1629,6 +1629,13 @@ recording::context::enable_dump (const char *dumpname,
 result *
 recording::context::compile ()
 {
+  if (m_populated_target_info)
+  {
+    add_error (NULL,
+      "cannot compile after calling gcc_jit_context_get_target_info");
+    return NULL;
+  }
+
   JIT_LOG_SCOPE (get_logger ());
 
   log_all_options ();
@@ -1659,6 +1666,13 @@ void
 recording::context::compile_to_file (enum gcc_jit_output_kind output_kind,
                                     const char *output_path)
 {
+  if (m_populated_target_info)
+  {
+    add_error (NULL,
+      "cannot compile after calling gcc_jit_context_get_target_info");
+    return;
+  }
+
   JIT_LOG_SCOPE (get_logger ());
 
   log_all_options ();
@@ -1677,6 +1691,28 @@ recording::context::compile_to_file (enum 
gcc_jit_output_kind output_kind,
   replayer.compile ();
 }
 
+void
+recording::context::populate_target_info ()
+{
+  JIT_LOG_SCOPE (get_logger ());
+
+  log_all_options ();
+
+  if (errors_occurred ())
+    return;
+
+  add_driver_option ("-fsyntax-only");
+  m_populated_target_info = true;
+
+  /* Set up a populate_target_info playback context.  */
+  ::gcc::jit::playback::populate_target_info replayer (this);
+
+  /* Use it.  */
+  replayer.compile ();
+
+  m_target_info = replayer.move_target_info ();
+}
+
 /* 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 0ac9245c2df5..4d41faa0446a 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "jit-common.h"
 #include "jit-logging.h"
+#include "jit-target.h"
 #include "libgccjit.h"
 
 #include <string>
@@ -328,6 +329,16 @@ public:
   compile_to_file (enum gcc_jit_output_kind output_kind,
                   const char *output_path);
 
+  void
+  populate_target_info ();
+
+  target_info *move_target_info ()
+  {
+    target_info *info = m_target_info;
+    m_target_info = nullptr;
+    return info;
+  }
+
   void
   add_error (location *loc, const char *fmt, ...)
       GNU_PRINTF(3, 4);
@@ -412,7 +423,11 @@ private:
   type *m_basic_types[NUM_GCC_JIT_TYPES];
   type *m_FILE_type;
 
+  bool m_populated_target_info = false;
+
   builtins_manager *m_builtins_manager; // lazily created
+
+  target_info *m_target_info;
 };
 
 
diff --git a/gcc/jit/jit-target-def.h b/gcc/jit/jit-target-def.h
new file mode 100644
index 000000000000..dcb342fafe7d
--- /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
+   <http://www.gnu.org/licenses/>.  */
+
+#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 000000000000..40b47971c44c
--- /dev/null
+++ b/gcc/jit/jit-target.cc
@@ -0,0 +1,96 @@
+/* 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
+<http://www.gnu.org/licenses/>.  */
+
+#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-playback.h"
+#include "jit-target.h"
+
+/* 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 CPU handler can override.  */
+  targetjitm.jit_register_cpu_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)
+{
+  gcc_assert (gcc::jit::active_playback_ctxt != NULL);
+  target_info* jit_target_info
+    = gcc::jit::active_playback_ctxt->get_target_info ();
+  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)
+{
+  gcc_assert (gcc::jit::active_playback_ctxt != NULL);
+  target_info* jit_target_info
+    = gcc::jit::active_playback_ctxt->get_target_info ();
+  jit_target_info->m_arch = arch;
+}
+
+void
+jit_target_add_supported_target_dependent_type (enum gcc_jit_types type_)
+{
+  gcc_assert (gcc::jit::active_playback_ctxt != NULL);
+  target_info* jit_target_info
+    = gcc::jit::active_playback_ctxt->get_target_info ();
+  jit_target_info->m_supported_target_dependent_types.insert (type_);
+}
+
+target_info *
+jit_get_target_info ()
+{
+  gcc_assert (gcc::jit::active_playback_ctxt != NULL);
+  target_info* info = gcc::jit::active_playback_ctxt->move_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 000000000000..5e657eb4e137
--- /dev/null
+++ b/gcc/jit/jit-target.def
@@ -0,0 +1,42 @@
+/* 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* 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}, which takes a key and a value.  The\n\
+keys added by this hook are made available at compile time by calling\n\
+get_target_info.",
+ 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 000000000000..626ae8179ff1
--- /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
+   <http://www.gnu.org/licenses/>.  */
+
+#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 <unordered_map>
+#include <unordered_set>
+
+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<const char *,
+       std::unordered_set<const char *, CStringHash, CStringEqual>,
+       CStringHash, CStringEqual>
+       m_info;
+    std::string m_arch;
+    std::unordered_set<enum gcc_jit_types> 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 725a5d53d06f..33369447074b 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "config.h"
 #define INCLUDE_MUTEX
+#define INCLUDE_STRING
 #include "system.h"
 #include "coretypes.h"
 #include "timevar.h"
@@ -29,6 +30,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 +46,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
 {
 };
@@ -3900,6 +3906,51 @@ gcc_jit_context_set_output_ident (gcc_jit_context *ctxt,
   ctxt->set_output_ident (output_ident);
 }
 
+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 ("populate_target_info of ctxt: %p", (void *)ctxt);
+
+  ctxt->populate_target_info ();
+
+  return (gcc_jit_target_info*) ctxt->move_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_VAL_IF_FAIL (info, 0, NULL, NULL, "NULL info");
+  RETURN_VAL_IF_FAIL (feature, 0, NULL, NULL, "NULL feature");
+  return info->has_target_value ("target_feature", feature);
+}
+
+const char *
+gcc_jit_target_info_arch (gcc_jit_target_info *info)
+{
+  RETURN_NULL_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_VAL_IF_FAIL (info, 0, 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.
 
    After error-checking, the real work is done by the
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index bc9fcaee2453..a58551007931 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.
 
@@ -2131,6 +2134,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_35; 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_35; 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_35; 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_35; 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_35; 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_35; 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 fcb6e6f2a55d..4662ca4b3c02 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -325,3 +325,12 @@ LIBGCCJIT_ABI_34 {
   global:
     gcc_jit_context_set_output_ident;
 } LIBGCCJIT_ABI_33;
+
+LIBGCCJIT_ABI_35 {
+  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_34;
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h 
b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index add5619aebd4..4aa18e3b7678 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -424,6 +424,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-error-target-info.c 
b/gcc/testsuite/jit.dg/test-error-target-info.c
new file mode 100644
index 000000000000..a2426458285d
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-target-info.c
@@ -0,0 +1,60 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#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);
+  gcc_jit_context_compile (ctxt);
+
+  gcc_jit_target_info_release (info);
+
+  /* Verify that the correct error message was emitted.  */
+  CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+    "cannot compile after calling gcc_jit_context_get_target_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;
+}
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 000000000000..edae18aa1143
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-target-info.c
@@ -0,0 +1,61 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#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);
+
+  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;
+}

Reply via email to