public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Rust frontend patches v1
@ 2022-07-27 13:40 herron.philip
  2022-07-27 13:40 ` [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder herron.philip
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: herron.philip @ 2022-07-27 13:40 UTC (permalink / raw)
  To: gcc-patches

This is the initial version 1 patch set for the Rust front-end. There are more changes that need to be extracted out for all the target hooks we have implemented. The goal is to see if we are implementing the target hooks information for x86 and arm. We have more patches for the other targets I can add in here but they all follow the pattern established here.

Each patch is buildable on its own and rebased ontop of 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we keep attribution for all the patches we have received in the front-end should we create a CONTRIBUTOR's file inside the front-end folder?

Note thanks to Thomas Schwinge and Mark Wielaard, we are keeping a branch up to date with our code on: https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master but this is not rebased ontop of gcc head.

Let me know if I have sent these patches correctly or not, this is a learning experience with git send-email.

[PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
[PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and
[PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
[PATCH Rust front-end v1 4/4] Add Rust front-end and associated


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
  2022-07-27 13:40 Rust frontend patches v1 herron.philip
@ 2022-07-27 13:40 ` herron.philip
  2022-07-27 13:40 ` [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 herron.philip
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: herron.philip @ 2022-07-27 13:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Philip Herron

From: Philip Herron <philip.herron@embecosm.com>

This is a skeleton front-end which is used so we can ensure each patch is
buildable:

gcc/rust/ChangeLog:

	* Make-lang.in
	* config-lang.in
	* lang-specs.h
	* lang.opt
	* rust-lang.cc
	* rustspec.cc
---
 gcc/rust/Make-lang.in   | 308 +++++++++++++++++++++++++++++++++++++
 gcc/rust/config-lang.in |  30 ++++
 gcc/rust/lang-specs.h   |  26 ++++
 gcc/rust/lang.opt       |  45 ++++++
 gcc/rust/rust-lang.cc   | 332 ++++++++++++++++++++++++++++++++++++++++
 gcc/rust/rustspec.cc    | 285 ++++++++++++++++++++++++++++++++++
 6 files changed, 1026 insertions(+)
 create mode 100644 gcc/rust/Make-lang.in
 create mode 100644 gcc/rust/config-lang.in
 create mode 100644 gcc/rust/lang-specs.h
 create mode 100644 gcc/rust/lang.opt
 create mode 100644 gcc/rust/rust-lang.cc
 create mode 100644 gcc/rust/rustspec.cc

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
new file mode 100644
index 00000000000..759960544c8
--- /dev/null
+++ b/gcc/rust/Make-lang.in
@@ -0,0 +1,308 @@
+# Make-lang.in -- Top level -*- makefile -*- fragment for GCC Rust frontend.
+
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# 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/>.
+
+# This file provides the language dependent support in the main Makefile.
+
+#RUST_EXES = rust
+
+# Use strict warnings for this front end.
+rust-warn = $(STRICT_WARN)
+
+# Installation name. Useful for cross compilers and used during install.
+GCCRS_INSTALL_NAME := $(shell echo gccrs|sed '$(program_transform_name)')
+GCCRS_TARGET_INSTALL_NAME := $(target_noncanonical)-$(shell echo gccrs|sed '$(program_transform_name)')
+
+# Define the names for selecting rust in LANGUAGES.
+rust: rust1$(exeext)
+
+# Tell GNU make to ignore files by these names if they exist.
+.PHONY: rust
+
+# removed GRS_CFLAGS from here
+
+CFLAGS-rust/rustspec.o += $(DRIVER_DEFINES)
+
+# Create the compiler driver gccrs.
+# A compiler driver is the program that interprets command argument and can be called from the command
+# line - e.g. gcc or g++, and not cc1, which is the actual compiler
+
+# Create driver objects
+GCCRS_D_OBJS = \
+   $(GCC_OBJS) \
+   rust/rustspec.o \
+   $(END)
+
+gccrs$(exeext): $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a $(LIBDEPS)
+	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	  $(GCCRS_D_OBJS) $(EXTRA_GCC_OBJS) libcommon-target.a \
+	  $(EXTRA_GCC_LIBS) $(LIBS)
+
+# List of host object files used by the rust language - files for translation from the parse tree
+# to GENERIC
+# The compiler proper, not driver
+GRS_OBJS = \
+    rust/rust-lang.o \
+    $(END)
+# removed object files from here
+
+# All language-specific object files for Rust.
+RUST_ALL_OBJS = $(GRS_OBJS) $(RUST_TARGET_OBJS)
+
+rust_OBJS = $(RUST_ALL_OBJS) rust/rustspec.o
+
+# The compiler itself is called rust1 (formerly grs1)
+rust1$(exeext): $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBDEPS)
+	+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
+	      $(RUST_ALL_OBJS) attribs.o $(BACKEND) $(LIBS) $(BACKENDLIBS)
+
+# Build hooks.
+
+lang_checks += check-rust
+lang_checks_parallelized += check-rust
+check_rust_parallelize = 10
+
+# Copies its dependencies into the source directory. This generally should be used for generated files
+# such as Bison output files which are not version-controlled, but should be included in any release
+# tarballs. This target will be executed during a bootstrap if ‘--enable-generated-files-in-srcdir’
+# was specified as a configure option.
+rust.srcextra:
+
+rust.all.cross: gccrs$(exeext)
+
+# idk what this does but someone used it
+rust.start.encap: gccrs$(exeext)
+rust.rest.encap:
+
+# Build generated man pages for the front end from Texinfo manuals (see Man Page Generation), in the
+# build directory. This target is only called if the necessary tools are available, but should ignore
+# errors so as not to stop the build if errors occur; man pages are optional and the tools involved
+# may be installed in a broken way.
+rust.man:
+
+# Copies its dependencies into the source directory. These targets will be executed during a bootstrap
+# if ‘--enable-generated-files-in-srcdir’ was specified as a configure option.
+rust.srcman:
+
+# Clean hooks.
+
+rust.mostlyclean:
+#	cd $(srcdir)/rust; rm -f *.o y.tab.h y.tab.c lex.yy.c
+
+rust.clean: rust.mostlyclean
+
+# Builds an etags TAGS file in the language subdirectory in the source tree.
+# TODO: add more directories if I add more
+rust.tags: force
+	cd $(srcdir)/rust; \
+	etags -o TAGS.sub *.y *.l *.cc *.h ast/*.h ast/*.cc lex/*.h lex/*.cc parse/*.h parse/*.cc; \
+	etags --include TAGS.sub --include ../TAGS.sub
+
+# Build documentation hooks.
+
+# Build info documentation for the front end, in the build directory. This target is only called by
+# ‘make bootstrap’ if a suitable version of makeinfo is available, so does not need to check for this,
+# and should fail if an error occurs.
+rust.info:
+
+rust.srcinfo:
+
+# Build DVI documentation for the front end, in the build directory. This should be done using
+# $(TEXI2DVI), with appropriate -I arguments pointing to directories of included files.
+rust.dvi:
+
+# Build PDF documentation for the front end, in the build directory. This should be done using
+# $(TEXI2PDF), with appropriate -I arguments pointing to directories of included files.
+rust.pdf:
+
+doc/rust.info:
+doc/rust.dvi:
+doc/rust.pdf:
+
+# Build HTML documentation for the front end, in the build directory.
+rust.html:
+
+# Install hooks.
+
+# Install everything that is part of the front end, apart from the compiler executables listed in
+# compilers in config-lang.in.
+rust.install-common: installdirs
+#	-rm -f $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+#	-rm -f $(DESTDIR)$(bindir)/$(GCCRS_TARGET_INSTALL_NAME)$(exeext)
+#	$(INSTALL_PROGRAM) gccrs$(exeext) $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+#	if test -f $(DESTDIR)$(bindir)$(GCCRS_TARGET_INSTALL_NAME)$(exeext); then \
+#	  :; \
+#	else \
+#	  cd $(DESTDIR)$(bindir) && \
+#	   $(LN) $(GCCRS_INSTALL_NAME)$(exeext) $(GCCRS_TARGET_INSTALL_NAME)$(exeext); \
+#	fi
+	-rm -f $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+	$(INSTALL_PROGRAM) gccrs$(exeext) $(DESTDIR)$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+	rm -f $(DESTDIR)$(bindir)/$(GCCRS_TARGET_INSTALL_NAME)$(exeext); \
+	( cd $(DESTDIR)$(bindir) && \
+      $(LN) $(GCCRS_INSTALL_NAME)$(exeext) $(GCCRS_TARGET_INSTALL_NAME)$(exeext) ); \
+
+# Install headers needed for plugins.
+rust.install-plugin:
+
+# Uninstall files installed by installing the compiler. This is currently documented not to be
+# supported, so the hook need not do anything.
+rust.uninstall:
+#	-rm -rf $(DESTDIR)/$(bindir)/$(GCCRS_INSTALL_NAME)$(exeext)
+	-rm -f gccrs$(exeext) grs1$(exeext)
+	-rm -f $(RUST_ALL_OBJS)
+# ^those two are a maybe
+
+# Enable selftests for the rust frontend
+selftest-rust: s-selftest-rust
+
+RUST_SELFTEST_FLAGS = -xrs $(SELFTEST_FLAGS)
+RUST_SELFTEST_DEPS = rust1$(exeext) $(SELFTEST_DEPS)
+
+# Run the rust selftests
+s-selftest-rust: $(RUST_SELFTEST_DEPS)
+	$(GCC_FOR_TARGET) $(RUST_SELFTEST_FLAGS)
+	$(STAMP) $@
+
+# Install info documentation for the front end, if it is present in the source directory. This target
+# should have dependencies on info files that should be installed.
+rust.install-info:
+
+rust.install-pdf:
+
+# Install man pages for the front end. This target should ignore errors.
+rust.install-man:
+
+# Stage hooks:
+# The toplevel makefile has already created stage?/rust at this point.
+# Used for handling bootstrap
+
+rust.stage1: stage1-start
+	-mv rust/*$(objext) stage1/rust
+rust.stage2: stage2-start
+	-mv rust/*$(objext) stage2/rust
+rust.stage3: stage3-start
+	-mv rust/*$(objext) stage3/rust
+rust.stage4: stage4-start
+	-mv rust/*$(objext) stage4/rust
+rust.stageprofile: stageprofile-start
+	-mv rust/*$(objext) stageprofile/rust
+rust.stagefeedback: stagefeedback-start
+	-mv rust/*$(objext) stagefeedback/rust
+
+CFLAGS-rust/rust-lang.o += -DDEFAULT_TARGET_VERSION=\"$(version)\" \
+	-DDEFAULT_TARGET_MACHINE=\"$(target_noncanonical)\"
+
+# cross-folder includes - add new folders later
+RUST_INCLUDES = -I $(srcdir)/rust \
+	-I $(srcdir)/rust/lex \
+	-I $(srcdir)/rust/parse \
+	-I $(srcdir)/rust/ast \
+	-I $(srcdir)/rust/analysis \
+	-I $(srcdir)/rust/backend \
+	-I $(srcdir)/rust/expand \
+	-I $(srcdir)/rust/hir/tree \
+	-I $(srcdir)/rust/hir \
+	-I $(srcdir)/rust/resolve \
+	-I $(srcdir)/rust/util \
+	-I $(srcdir)/rust/typecheck \
+	-I $(srcdir)/rust/checks/lints \
+	-I $(srcdir)/rust/checks/errors \
+	-I $(srcdir)/rust/checks/errors/privacy \
+	-I $(srcdir)/rust/util \
+        -I $(srcdir)/rust/metadata
+
+# add files that require cross-folder includes - currently rust-lang.o, rust-lex.o
+CFLAGS-rust/rust-lang.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-lex.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-parse.o += $(RUST_INCLUDES)
+CFLAGS-rust/rust-session-manager.o += $(RUST_INCLUDES)
+
+# TODO: possibly find a way to ensure C++11 compilation level here?
+RUST_CXXFLAGS = -std=c++11 -Wno-unused-parameter -Werror=overloaded-virtual
+
+# build all rust/lex files in rust folder, add cross-folder includes
+rust/%.o: rust/lex/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build all rust/parse files in rust folder, add cross-folder includes
+rust/%.o: rust/parse/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/ast files in rust folder
+rust/%.o: rust/ast/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/backend files in rust folder
+rust/%.o: rust/backend/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/expand files in rust folder
+rust/%.o: rust/expand/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/util files in rust folder
+rust/%.o: rust/util/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/hir files in rust folder
+rust/%.o: rust/hir/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/hir/tree files in rust folder
+rust/%.o: rust/hir/tree/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/resolve files in rust folder
+rust/%.o: rust/resolve/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/typecheck files in rust folder
+rust/%.o: rust/typecheck/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/checks/lints files in rust folder
+rust/%.o: rust/checks/lints/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/checks/errors files in rust folder
+rust/%.o: rust/checks/errors/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build privacy pass files in rust folder
+rust/%.o: rust/checks/errors/privacy/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
+
+# build rust/metadata files in rust folder
+rust/%.o: rust/metadata/%.cc
+	$(COMPILE) $(RUST_CXXFLAGS) $(RUST_INCLUDES) $<
+	$(POSTCOMPILE)
diff --git a/gcc/rust/config-lang.in b/gcc/rust/config-lang.in
new file mode 100644
index 00000000000..9196b6cf417
--- /dev/null
+++ b/gcc/rust/config-lang.in
@@ -0,0 +1,30 @@
+# config-lang.in -- Top level configure fragment for gcc Rust frontend.
+
+# Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+# This file is part of GCC.
+
+# 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/>.
+
+# Configure looks for the existence of this file to auto-config each language.
+# We define several parameters used by configure:
+#
+# language	- name of language as it would appear in $(LANGUAGES)
+# compilers	- value to add to $(COMPILERS)
+
+language="rust"
+compilers="rust1\$(exeext)"
+build_by_default="no"
+gtfiles="\$(srcdir)/rust/rust-lang.cc"
diff --git a/gcc/rust/lang-specs.h b/gcc/rust/lang-specs.h
new file mode 100644
index 00000000000..9b14a559dd6
--- /dev/null
+++ b/gcc/rust/lang-specs.h
@@ -0,0 +1,26 @@
+/* lang-specs.h -- gcc driver specs for Rust frontend.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   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/>.  */
+
+/* This is the contribution to the `default_compilers' array in gcc.cc
+   for the Rust language.  */
+
+{".rs", "@rs", 0, 1, 0},
+  {"@rs",
+   "rust1 %i %(cc1_options) %{I*} %{L*} %D %{!fsyntax-only:%(invoke_as)}", 0, 1,
+   0},
diff --git a/gcc/rust/lang.opt b/gcc/rust/lang.opt
new file mode 100644
index 00000000000..5a23711278e
--- /dev/null
+++ b/gcc/rust/lang.opt
@@ -0,0 +1,45 @@
+; Options for the Rust front end.
+; Copyright (C) 2003-2022 Free Software Foundation, Inc.
+;
+; This file is part of GCC.
+;
+; 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/>.
+
+; See the GCC internals manual for a description of this file's format.
+
+; Please try to keep this file in ASCII collating order.
+
+; Describes command-line options used by this frontend
+
+Language
+Rust
+
+I
+Rust Joined Separate
+; Documented in c.opt
+
+L
+Rust Joined Separate
+; Not documented
+
+Wall
+Rust
+; Documented in c.opt
+
+o
+Rust Joined Separate
+; Documented in common.opt
+
+; This comment is to ensure we retain the blank line above.
diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
new file mode 100644
index 00000000000..5592129addf
--- /dev/null
+++ b/gcc/rust/rust-lang.cc
@@ -0,0 +1,332 @@
+// Copyright (C) 2020-2022 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// 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/>.
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "target.h"
+#include "tree.h"
+#include "gimple-expr.h"
+#include "diagnostic.h"
+#include "opts.h"
+#include "fold-const.h"
+#include "gimplify.h"
+#include "stor-layout.h"
+#include "debug.h"
+#include "convert.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "options.h"
+#include <mpfr.h>
+
+// Language-dependent contents of a type. GTY() mark used for garbage collector.
+struct GTY (()) lang_type
+{
+  char dummy;
+};
+
+// Language-dependent contents of a decl.
+struct GTY (()) lang_decl
+{
+  char dummy;
+};
+
+// Language-dependent contents of an identifier.  This must include a
+// tree_identifier.
+struct GTY (()) lang_identifier
+{
+  struct tree_identifier common;
+};
+
+// The resulting tree type.
+union GTY ((
+  desc ("TREE_CODE (&%h.generic) == IDENTIFIER_NODE"),
+  chain_next (
+    "CODE_CONTAINS_STRUCT (TREE_CODE (&%h.generic), "
+    "TS_COMMON) ? ((union lang_tree_node *) TREE_CHAIN (&%h.generic)) : NULL")))
+  lang_tree_node
+{
+  union tree_node GTY ((tag ("0"), desc ("tree_node_structure (&%h)"))) generic;
+  struct lang_identifier GTY ((tag ("1"))) identifier;
+};
+
+// We don't use language_function.
+struct GTY (()) language_function
+{
+  int dummy;
+};
+
+/* Language hooks.  */
+
+tree
+convert (tree type, tree expr)
+{
+  if (type == error_mark_node || expr == error_mark_node
+      || TREE_TYPE (expr) == error_mark_node)
+    return error_mark_node;
+
+  if (type == TREE_TYPE (expr))
+    return expr;
+
+  if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (expr)))
+    return fold_convert (type, expr);
+
+  switch (TREE_CODE (type))
+    {
+    case VOID_TYPE:
+    case BOOLEAN_TYPE:
+      return fold_convert (type, expr);
+    case INTEGER_TYPE:
+      return fold (convert_to_integer (type, expr));
+    case POINTER_TYPE:
+      return fold (convert_to_pointer (type, expr));
+    case REAL_TYPE:
+      return fold (convert_to_real (type, expr));
+    case COMPLEX_TYPE:
+      return fold (convert_to_complex (type, expr));
+    default:
+      break;
+    }
+
+  gcc_unreachable ();
+}
+
+/* Initial lang hook called (possibly), used for initialisation.
+ * Must call build_common_tree_nodes, set_sizetype, build_common_tree_nodes_2,
+ * and build_common_builtin_nodes, as well as set global variable
+ * void_list_node. Apparently called after option handling? */
+static bool
+grs_langhook_init (void)
+{
+  /* Something to do with this:
+   This allows the code in d-builtins.cc to not have to worry about
+   converting (C signed char *) to (D char *) for string arguments of
+   built-in functions. The parameter (signed_char = false) specifies
+   whether char is signed.  */
+  build_common_tree_nodes (false);
+
+  // Creates a new TREE_LIST node with purpose NULL_TREE and value
+  // void_type_node
+  void_list_node = build_tree_list (NULL_TREE, void_type_node);
+
+  // Builds built-ins for middle-end after all front-end built-ins are already
+  // instantiated
+  build_common_builtin_nodes ();
+
+  mpfr_set_default_prec (128);
+
+  using_eh_for_cleanups ();
+
+  return true;
+}
+
+/* The option mask (something to do with options for specific frontends or
+ * something). */
+static unsigned int
+grs_langhook_option_lang_mask (void)
+{
+  return CL_Rust;
+}
+
+/* Initialize the options structure. */
+static void
+grs_langhook_init_options_struct (struct gcc_options * /* opts */)
+{}
+
+/* Main entry point for front-end, apparently. Finds input file names in global
+ * vars in_fnames and num_in_fnames. From this, frontend can take over and do
+ * actual parsing and initial compilation. This function must create a complete
+ * parse tree in a global var, and then return.
+ *
+ * Some consider this the "start of compilation". */
+static void
+grs_langhook_parse_file (void)
+{}
+
+/* Seems to get the exact type for a specific type - e.g. for scalar float with
+ * 32-bit bitsize, it returns float, and for 64-bit bitsize, it returns double.
+ * Used to map RTL nodes to machine modes or something like that. */
+static tree
+grs_langhook_type_for_mode (machine_mode mode, int unsignedp)
+{
+  if (mode == TYPE_MODE (float_type_node))
+    return float_type_node;
+
+  if (mode == TYPE_MODE (double_type_node))
+    return double_type_node;
+
+  if (mode == TYPE_MODE (intQI_type_node)) // quarter integer mode - single byte
+					   // treated as integer
+    return unsignedp ? unsigned_intQI_type_node : intQI_type_node;
+  if (mode
+      == TYPE_MODE (intHI_type_node)) // half integer mode - two-byte integer
+    return unsignedp ? unsigned_intHI_type_node : intHI_type_node;
+  if (mode
+      == TYPE_MODE (intSI_type_node)) // single integer mode - four-byte integer
+    return unsignedp ? unsigned_intSI_type_node : intSI_type_node;
+  if (mode
+      == TYPE_MODE (
+	intDI_type_node)) // double integer mode - eight-byte integer
+    return unsignedp ? unsigned_intDI_type_node : intDI_type_node;
+  if (mode
+      == TYPE_MODE (intTI_type_node)) // tetra integer mode - 16-byte integer
+    return unsignedp ? unsigned_intTI_type_node : intTI_type_node;
+
+  if (mode == TYPE_MODE (integer_type_node))
+    return unsignedp ? unsigned_type_node : integer_type_node;
+
+  if (mode == TYPE_MODE (long_integer_type_node))
+    return unsignedp ? long_unsigned_type_node : long_integer_type_node;
+
+  if (mode == TYPE_MODE (long_long_integer_type_node))
+    return unsignedp ? long_long_unsigned_type_node
+		     : long_long_integer_type_node;
+
+  if (COMPLEX_MODE_P (mode))
+    {
+      if (mode == TYPE_MODE (complex_float_type_node))
+	return complex_float_type_node;
+      if (mode == TYPE_MODE (complex_double_type_node))
+	return complex_double_type_node;
+      if (mode == TYPE_MODE (complex_long_double_type_node))
+	return complex_long_double_type_node;
+      if (mode == TYPE_MODE (complex_integer_type_node) && !unsignedp)
+	return complex_integer_type_node;
+    }
+  /* gcc_unreachable */
+  return NULL;
+}
+
+// Record a builtin function. We just ignore builtin functions.
+static tree
+grs_langhook_builtin_function (tree decl ATTRIBUTE_UNUSED)
+{
+  return decl;
+}
+
+static bool
+grs_langhook_global_bindings_p (void)
+{
+  return false;
+}
+
+static tree
+grs_langhook_pushdecl (tree decl ATTRIBUTE_UNUSED)
+{
+  gcc_unreachable ();
+  return NULL;
+}
+
+static tree
+grs_langhook_getdecls (void)
+{
+  return NULL;
+}
+
+static bool
+grs_langhook_handle_option (
+  size_t scode ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED,
+  HOST_WIDE_INT value ATTRIBUTE_UNUSED, int kind ATTRIBUTE_UNUSED,
+  location_t loc ATTRIBUTE_UNUSED,
+  const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
+{
+  return false;
+}
+
+static bool
+grs_langhook_post_options (const char **pfilename ATTRIBUTE_UNUSED)
+{
+  /* Returning false means that the backend should be used.  */
+  return false;
+}
+
+/* Rust-specific gimplification. May need to gimplify e.g.
+ * CALL_EXPR_STATIC_CHAIN */
+static int
+grs_langhook_gimplify_expr (tree *expr_p ATTRIBUTE_UNUSED,
+			    gimple_seq *pre_p ATTRIBUTE_UNUSED,
+			    gimple_seq *post_p ATTRIBUTE_UNUSED)
+{
+  return GS_UNHANDLED;
+}
+
+static tree
+grs_langhook_eh_personality (void)
+{
+  return error_mark_node;
+}
+
+/* FIXME: This is a hack to preserve trees that we create from the
+   garbage collector.  */
+
+static GTY (()) tree rust_gc_root;
+
+void
+rust_preserve_from_gc (tree t)
+{
+  rust_gc_root = tree_cons (NULL_TREE, t, rust_gc_root);
+}
+
+/* Convert an identifier for use in an error message.  */
+
+const char *
+rust_localize_identifier (const char *ident)
+{
+  return identifier_to_locale (ident);
+}
+
+/* The language hooks data structure. This is the main interface between the GCC
+ * front-end and the GCC middle-end/back-end. A list of language hooks could be
+ * found in <gcc>/langhooks.h
+ */
+#undef LANG_HOOKS_NAME
+#undef LANG_HOOKS_INIT
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#undef LANG_HOOKS_INIT_OPTIONS_STRUCT
+#undef LANG_HOOKS_HANDLE_OPTION
+#undef LANG_HOOKS_POST_OPTIONS
+#undef LANG_HOOKS_PARSE_FILE
+#undef LANG_HOOKS_TYPE_FOR_MODE
+#undef LANG_HOOKS_BUILTIN_FUNCTION
+#undef LANG_HOOKS_GLOBAL_BINDINGS_P
+#undef LANG_HOOKS_PUSHDECL
+#undef LANG_HOOKS_GETDECLS
+#undef LANG_HOOKS_WRITE_GLOBALS
+#undef LANG_HOOKS_GIMPLIFY_EXPR
+#undef LANG_HOOKS_EH_PERSONALITY
+
+#define LANG_HOOKS_NAME "GNU Rust"
+#define LANG_HOOKS_INIT grs_langhook_init
+#define LANG_HOOKS_OPTION_LANG_MASK grs_langhook_option_lang_mask
+#define LANG_HOOKS_INIT_OPTIONS_STRUCT grs_langhook_init_options_struct
+#define LANG_HOOKS_HANDLE_OPTION grs_langhook_handle_option
+#define LANG_HOOKS_POST_OPTIONS grs_langhook_post_options
+#define LANG_HOOKS_PARSE_FILE grs_langhook_parse_file
+#define LANG_HOOKS_TYPE_FOR_MODE grs_langhook_type_for_mode
+#define LANG_HOOKS_BUILTIN_FUNCTION grs_langhook_builtin_function
+#define LANG_HOOKS_GLOBAL_BINDINGS_P grs_langhook_global_bindings_p
+#define LANG_HOOKS_PUSHDECL grs_langhook_pushdecl
+#define LANG_HOOKS_GETDECLS grs_langhook_getdecls
+#define LANG_HOOKS_GIMPLIFY_EXPR grs_langhook_gimplify_expr
+#define LANG_HOOKS_EH_PERSONALITY grs_langhook_eh_personality
+
+// Expands all LANG_HOOKS_x of GCC
+struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
+
+#include "gt-rust-rust-lang.h"
+#include "gtype-rust.h"
diff --git a/gcc/rust/rustspec.cc b/gcc/rust/rustspec.cc
new file mode 100644
index 00000000000..eb49444cade
--- /dev/null
+++ b/gcc/rust/rustspec.cc
@@ -0,0 +1,285 @@
+/* rustspec.c -- Specific flags and argument handling of the gcc Rust front end.
+   Copyright (C) 2009-2022 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+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/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "opts.h"
+
+// satisfy intellisense
+#include "options.h"
+
+/* This bit is set if we saw a `-xfoo' language specification.  */
+#define LANGSPEC (1 << 1)
+/* This bit is set if they did `-lc'.  */
+#define WITHLIBC (1 << 2)
+/* Skip this option.  */
+#define SKIPOPT (1 << 3)
+
+void
+lang_specific_driver (struct cl_decoded_option **in_decoded_options,
+		      unsigned int *in_decoded_options_count,
+		      int *in_added_libraries)
+{
+  unsigned int i, j;
+
+  /* This is a tristate:
+     -1 means we should not link in librust
+     0  means we should link in librust if it is needed
+     1  means librust is needed and should be linked in.
+     2  means librust is needed and should be linked statically.  */
+  int library = 0;
+
+  /* The new argument list will be contained in this.  */
+  struct cl_decoded_option *new_decoded_options;
+
+  /* "-lc" if it appears on the command line.  */
+  const struct cl_decoded_option *saw_libc = 0;
+
+  /* An array used to flag each argument that needs a bit set for
+     LANGSPEC or WITHLIBC.  */
+  int *args;
+
+  /* True if we saw -static.  */
+  int static_link = 0;
+
+  /* True if we should add -shared-libgcc to the command-line.  */
+  int shared_libgcc = 1;
+
+  /* The total number of arguments with the new stuff.  */
+  unsigned int argc;
+
+  /* The argument list.  */
+  struct cl_decoded_option *decoded_options;
+
+  /* The number of libraries added in.  */
+  int added_libraries;
+
+  /* The total number of arguments with the new stuff.  */
+  int num_args = 1;
+
+  /* Whether the -o option was used.  */
+  bool saw_opt_o = false;
+
+  /* Whether the -c option was used.  Also used for -E, -fsyntax-only,
+     in general anything which implies only compilation and not
+     linking.  */
+  bool saw_opt_c = false;
+
+  /* Whether the -S option was used.  */
+  bool saw_opt_S = false;
+
+  /* The first input file with an extension of .rs.  */
+  const char *first_rust_file = NULL;
+
+  argc = *in_decoded_options_count;
+  decoded_options = *in_decoded_options;
+  added_libraries = *in_added_libraries;
+
+  args = XCNEWVEC (int, argc);
+
+  for (i = 1; i < argc; i++)
+    {
+      const char *arg = decoded_options[i].arg;
+
+      switch (decoded_options[i].opt_index)
+	{
+	case OPT_r:
+	case OPT_nostdlib:
+	case OPT_nodefaultlibs:
+	  library = -1;
+	  break;
+
+	case OPT_l:
+	  if (strcmp (arg, "c") == 0)
+	    args[i] |= WITHLIBC;
+	  else
+	    /* Unrecognized libraries (e.g. -lfoo) may require librust.  */
+	    library = (library == 0) ? 1 : library;
+	  break;
+
+	case OPT_x:
+	  if (library == 0 && strcmp (arg, "rust") == 0)
+	    library = 1;
+	  break;
+
+	case OPT_Xlinker:
+	case OPT_Wl_:
+	  /* Arguments that go directly to the linker might be .o files,
+	     or something, and so might cause librust to be needed.  */
+	  if (library == 0)
+	    library = 1;
+	  break;
+
+	case OPT_c:
+	case OPT_E:
+	case OPT_M:
+	case OPT_MM:
+	case OPT_fsyntax_only:
+	  /* Don't specify libraries if we won't link, since that would
+	     cause a warning.  */
+	  saw_opt_c = true;
+	  library = -1;
+	  break;
+
+	case OPT_S:
+	  saw_opt_S = true;
+	  library = -1;
+	  break;
+
+	case OPT_o:
+	  saw_opt_o = true;
+	  break;
+
+	case OPT_static:
+	  static_link = 1;
+	  break;
+
+	case OPT_static_libgcc:
+	  shared_libgcc = 0;
+	  break;
+
+	case OPT_SPECIAL_input_file:
+	  if (library == 0)
+	    library = 1;
+
+	  if (first_rust_file == NULL)
+	    {
+	      int len;
+
+	      len = strlen (arg);
+	      if (len > 3 && strcmp (arg + len - 3, ".rs") == 0)
+		first_rust_file = arg;
+	    }
+
+	  break;
+	}
+    }
+
+    /* There's no point adding -shared-libgcc if we don't have a shared
+       libgcc.  */
+#ifndef ENABLE_SHARED_LIBGCC
+  shared_libgcc = 0;
+#endif
+
+  /* Make sure to have room for the trailing NULL argument.  */
+  num_args = argc + shared_libgcc + (library > 0) * 5 + 10;
+  new_decoded_options = XNEWVEC (struct cl_decoded_option, num_args);
+
+  i = 0;
+  j = 0;
+
+  /* Copy the 0th argument, i.e., the name of the program itself.  */
+  new_decoded_options[j++] = decoded_options[i++];
+
+  /* NOTE: We start at 1 now, not 0.  */
+  while (i < argc)
+    {
+      new_decoded_options[j] = decoded_options[i];
+
+      if (!saw_libc && (args[i] & WITHLIBC) && library > 0)
+	{
+	  --j;
+	  saw_libc = &decoded_options[i];
+	}
+
+      if ((args[i] & SKIPOPT) != 0)
+	--j;
+
+      i++;
+      j++;
+    }
+
+  /* If we didn't see a -o option, add one.  This is because we need
+     the driver to pass all .rs files to rust1.  Without a -o option the
+     driver will invoke rust1 separately for each input file.  FIXME:
+     This should probably use some other interface to force the driver
+     to set combine_inputs.  */
+  if (first_rust_file != NULL && !saw_opt_o)
+    {
+      if (saw_opt_c || saw_opt_S)
+	{
+	  const char *base;
+	  int baselen;
+	  int alen;
+	  char *out;
+
+	  base = lbasename (first_rust_file);
+	  baselen = strlen (base) - 3;
+	  alen = baselen + 3;
+	  out = XNEWVEC (char, alen);
+	  memcpy (out, base, baselen);
+	  /* The driver will convert .o to some other suffix (e.g.,
+	     .obj) if appropriate.  */
+	  out[baselen] = '.';
+	  if (saw_opt_S)
+	    out[baselen + 1] = 's';
+	  else
+	    out[baselen + 1] = 'o';
+	  out[baselen + 2] = '\0';
+	  generate_option (OPT_o, out, 1, CL_DRIVER, &new_decoded_options[j]);
+	}
+      else
+	generate_option (OPT_o, "a.out", 1, CL_DRIVER, &new_decoded_options[j]);
+      j++;
+    }
+
+  /* Add `-lrust' if we haven't already done so.  */
+  if (library > 0)
+    {
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+	{
+	  generate_option (OPT_Wl_, LD_STATIC_OPTION, 1, CL_DRIVER,
+			   &new_decoded_options[j]);
+	  j++;
+	}
+#endif
+
+#ifdef HAVE_LD_STATIC_DYNAMIC
+      if (library > 1 && !static_link)
+	{
+	  generate_option (OPT_Wl_, LD_DYNAMIC_OPTION, 1, CL_DRIVER,
+			   &new_decoded_options[j]);
+	  j++;
+	}
+#endif
+    }
+
+  if (saw_libc)
+    new_decoded_options[j++] = *saw_libc;
+  if (shared_libgcc && !static_link)
+    generate_option (OPT_shared_libgcc, NULL, 1, CL_DRIVER,
+		     &new_decoded_options[j++]);
+
+  *in_decoded_options_count = j;
+  *in_decoded_options = new_decoded_options;
+  *in_added_libraries = added_libraries;
+}
+
+/* Called before linking.  Returns 0 on success and -1 on failure.  */
+int
+lang_specific_pre_link (void) /* Not used for Rust.  */
+{
+  return 0;
+}
+
+/* Number of extra output files that lang_specific_pre_link may generate.  */
+int lang_specific_extra_outfiles = 0; /* Not used for Rust.  */
-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-27 13:40 Rust frontend patches v1 herron.philip
  2022-07-27 13:40 ` [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder herron.philip
@ 2022-07-27 13:40 ` herron.philip
  2022-07-28  9:57   ` Jakub Jelinek
  2022-07-28 10:38   ` Thomas Schwinge
  2022-07-27 13:40 ` [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM herron.philip
  2022-07-27 16:45 ` Rust frontend patches v1 David Malcolm
  3 siblings, 2 replies; 20+ messages in thread
From: herron.philip @ 2022-07-27 13:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Philip Herron, SimplyTheOther

From: Philip Herron <philip.herron@embecosm.com>

This patch introduces a new set of interfaces to define the target info as
expected by the rust front-end. It takes advantage of the information
within gcc/config/target directories which gets called by the front-end
to populate rust front-end datastructures by calling into:
builtin_rust_info. This patch has been isolated to find if we are
approaching this in an idiomatic way and is compilable without the
rust-front-end code.

We have received many patches here which gives us the target hook info for
most platforms but getting the normal x86 done correctly will define if
the other patches are done correctly.

gcc/doc/ChangeLog:

        * tm.texi.in: specifiy hooks for rust target info
        * tm.texi: commit the generated documentation

gcc/ChangeLog:

        * Makefile.in: add target to generate rust hooks
        * config.gcc: add rust target interface to be compiled for i386
	* genhooks.cc: generate rust target hooks
	* configure: autoconf update
	* configure.ac: add tm_rust_file_list and tm_rust_include_list

gcc/config/ChangeLog:

        * default-rust.cc: new target hooks initializer for rust
        * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
	* dragonfly.h: define TARGET_RUST_OS_INFO
	* freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
	* freebsd.h: define guard for TARGET_RUST_OS_INFO
	* fuchsia.h: define TARGET_RUST_OS_INFO
	* kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
	* kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
	* linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
	* linux.h: define GNU_USER_TARGET_RUST_OS_INFO
	* netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
	* openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
	* phoenix.h: define TARGET_RUST_OS_INFO
	* sol2.h: define TARGET_RUST_OS_INFO
	* vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
	* vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO

gcc/config/i386/ChangeLog:

        * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
        * cygming.h: define TARGET_RUST_OS_INFO
        * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
        * darwin.h: define TARGET_RUST_OS_INFO
        * djgpp.h: likewise
        * gnu-user-common.h: define TARGET_RUST_OS_INFO
        * i386-protos.h: prototype for ix86_rust_target_cpu_info
        * i386-rust.cc: new file to generate the rust target host info
        * i386.h: define TARGET_RUST_CPU_INFO hook
        * linux-common.h: define hooks for target info
        * lynx.h: likewise
        * mingw32.h: likewise
        * netbsd-elf.h: likewise
        * netbsd64.h: likewise
        * nto.h: likewise
        * openbsdelf.h: likewise
        * rdos.h: likewise
        * rtemself.h: likewise
        * t-i386: add makefilke rule for i386-rust.cc
        * vxworks.h: define TARGET_RUST_OS_INFO

gcc/rust/ChangeLog:

        * rust-target-def.h: define the headers to access the hooks
        * rust-target.def: define the hooks nessecary based on C90
        * rust-target.h: define extern gcc_targetrustm

Co-authored-by: SimplyTheOther <simplytheother@gmail.com>
---
 gcc/Makefile.in                   |  35 ++-
 gcc/config.gcc                    |  17 +
 gcc/config/default-rust.cc        |  26 ++
 gcc/config/dragonfly.h            |  12 +
 gcc/config/freebsd-spec.h         |   9 +
 gcc/config/freebsd.h              |   5 +
 gcc/config/fuchsia.h              |  16 +
 gcc/config/gnu.h                  |  12 +
 gcc/config/i386/crtdll.h          |  12 +
 gcc/config/i386/cygming.h         |   5 +
 gcc/config/i386/cygwin.h          |  10 +
 gcc/config/i386/darwin.h          |  10 +
 gcc/config/i386/djgpp.h           |   9 +
 gcc/config/i386/gnu-user-common.h |   5 +
 gcc/config/i386/i386-protos.h     |   3 +
 gcc/config/i386/i386-rust.cc      | 501 ++++++++++++++++++++++++++++++
 gcc/config/i386/i386.h            |   3 +
 gcc/config/i386/linux-common.h    |  17 +
 gcc/config/i386/lynx.h            |   9 +
 gcc/config/i386/mingw32.h         |   8 +
 gcc/config/i386/netbsd-elf.h      |   5 +
 gcc/config/i386/netbsd64.h        |   5 +
 gcc/config/i386/nto.h             |  12 +
 gcc/config/i386/openbsdelf.h      |   5 +
 gcc/config/i386/rdos.h            |  11 +
 gcc/config/i386/rtemself.h        |  10 +
 gcc/config/i386/t-i386            |   4 +
 gcc/config/i386/vxworks.h         |   5 +
 gcc/config/kfreebsd-gnu.h         |   8 +
 gcc/config/kopensolaris-gnu.h     |  12 +
 gcc/config/linux-android.h        |  12 +
 gcc/config/linux.h                |  14 +
 gcc/config/netbsd.h               |   9 +
 gcc/config/openbsd.h              |   8 +
 gcc/config/phoenix.h              |  12 +
 gcc/config/sol2.h                 |  10 +
 gcc/config/vxworks.h              |   8 +
 gcc/config/vxworksae.h            |   9 +
 gcc/configure                     |  19 ++
 gcc/configure.ac                  |  19 ++
 gcc/doc/tm.texi                   |  17 +
 gcc/doc/tm.texi.in                |   9 +
 gcc/genhooks.cc                   |   1 +
 gcc/rust/rust-target-def.h        |  20 ++
 gcc/rust/rust-target.def          |  89 ++++++
 gcc/rust/rust-target.h            |  47 +++
 46 files changed, 1101 insertions(+), 3 deletions(-)
 create mode 100644 gcc/config/default-rust.cc
 create mode 100644 gcc/config/i386/i386-rust.cc
 create mode 100644 gcc/rust/rust-target-def.h
 create mode 100644 gcc/rust/rust-target.def
 create mode 100644 gcc/rust/rust-target.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 001506f8abf..e5a15b8b667 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -573,6 +573,8 @@ tm_p_file_list=@tm_p_file_list@
 tm_p_include_list=@tm_p_include_list@
 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@
 build_xm_file_list=@build_xm_file_list@
 build_xm_include_list=@build_xm_include_list@
 build_xm_defines=@build_xm_defines@
@@ -866,6 +868,7 @@ CONFIG_H  = config.h  $(host_xm_file_list)
 TCONFIG_H = tconfig.h $(xm_file_list)
 TM_P_H    = tm_p.h    $(tm_p_file_list)
 TM_D_H    = tm_d.h    $(tm_d_file_list)
+TM_RUST_H = tm_rust.h $(tm_rust_file_list)
 GTM_H     = tm.h      $(tm_file_list) insn-constants.h
 TM_H      = $(GTM_H) insn-flags.h $(OPTIONS_H)
 
@@ -928,6 +931,7 @@ 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)
 MACHMODE_H = machmode.h mode-classes.def
 HOOKS_H = hooks.h
 HOSTHOOKS_DEF_H = hosthooks-def.h $(HOOKS_H)
@@ -1228,6 +1232,9 @@ CXX_TARGET_OBJS=@cxx_target_objs@
 # Target specific, D specific object file
 D_TARGET_OBJS=@d_target_objs@
 
+# Target specific, Rust specific object file
+RUST_TARGET_OBJS=@rust_target_objs@
+
 # Target specific, Fortran specific object file
 FORTRAN_TARGET_OBJS=@fortran_target_objs@
 
@@ -1937,6 +1944,7 @@ tconfig.h: cs-tconfig.h ; @true
 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
 
 cs-config.h: Makefile
 	TARGET_CPU_DEFAULT="" \
@@ -1968,6 +1976,11 @@ cs-tm_d.h: Makefile
 	HEADERS="$(tm_d_include_list)" DEFINES="" \
 	$(SHELL) $(srcdir)/mkconfig.sh tm_d.h
 
+cs-tm_rust.h: Makefile
+	TARGET_CPU_DEFAULT="" \
+	HEADERS="$(tm_rust_include_list)" DEFINES="" \
+	$(SHELL) $(srcdir)/mkconfig.sh tm_rust.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
@@ -2304,6 +2317,12 @@ default-d.o: config/default-d.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+# Files used by the Rust language front end.
+
+default-rust.o: config/default-rust.c
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 # Language-independent files.
 
 DRIVER_DEFINES = \
@@ -2609,6 +2628,15 @@ s-d-target-hooks-def-h: build/genhooks$(build_exeext)
 					     d/d-target-hooks-def.h
 	$(STAMP) s-d-target-hooks-def-h
 
+rust/rust-target-hooks-def.h: s-rust-target-hooks-def-h; @true
+
+s-rust-target-hooks-def-h: build/genhooks$(build_exeext)
+	$(RUN_GEN) build/genhooks$(build_exeext) "Rust Target Hook" \
+					     > tmp-rust-target-hooks-def.h
+	$(SHELL) $(srcdir)/../move-if-change tmp-rust-target-hooks-def.h \
+					     rust/rust-target-hooks-def.h
+	$(STAMP) s-rust-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
@@ -2633,6 +2661,7 @@ s-tm-texi: build/genhooks$(build_exeext) $(srcdir)/doc/tm.texi.in
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/c-family/c-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/common/common-target.def \
 	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/d/d-target.def \
+	    || test $(srcdir)/doc/tm.texi -nt $(srcdir)/rust/rust-target.def \
 	  ); then \
 	  echo >&2 ; \
 	  echo You should edit $(srcdir)/doc/tm.texi.in rather than $(srcdir)/doc/tm.texi . >&2 ; \
@@ -2782,8 +2811,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_RUST_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 \
@@ -2791,7 +2820,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_D_H) $(TM_H) multilib.h \
        common/common-target-hooks-def.h pass-instances.def \
        gimple-match.cc generic-match.cc \
        c-family/c-target-hooks-def.h d/d-target-hooks-def.h \
-       case-cfn-macros.h \
+       rust/rust-target-hooks-def.h case-cfn-macros.h \
        cfn-operators.pd omp-device-properties.h
 
 #\f
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4e3b15bb5e9..cdd4fb4392a 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -90,6 +90,9 @@
 #  tm_d_file		A list of headers with definitions of target hook
 #			macros for the D compiler.
 #
+#  tm_rust_file		A list of headers with definitions of target hook
+#			macros for the Rust compiler.
+#
 #  out_file		The name of the machine description C support
 #			file, if different from "$cpu_type/$cpu_type.c".
 #
@@ -146,6 +149,9 @@
 #  d_target_objs	List of extra target-dependent objects that be
 #			linked into the D compiler only.
 #
+#  rust_target_objs	List of extra target-dependent objects that be
+#			linked into the Rust compiler only.
+#
 #  fortran_target_objs	List of extra target-dependent objects that be
 #			linked into the fortran compiler only.
 #
@@ -201,6 +207,9 @@
 #
 #  target_has_targetdm	Set to yes or no depending on whether the target
 #			has its own definition of targetdm.
+#
+#  target_has_targetrustm	Set to yes or no depending on whether the target
+#			has its own definition of targetrustm.
 
 out_file=
 common_out_file=
@@ -217,6 +226,7 @@ extra_options=
 c_target_objs=
 cxx_target_objs=
 d_target_objs=
+rust_target_objs=
 fortran_target_objs=
 target_has_targetcm=no
 target_has_targetm_common=yes
@@ -391,6 +401,7 @@ i[34567]86-*-* | x86_64-*-*)
 	c_target_objs="i386-c.o"
 	cxx_target_objs="i386-c.o"
 	d_target_objs="i386-d.o"
+	rust_target_objs="i386-rust.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"
@@ -560,10 +571,12 @@ esac
 
 tm_file=${cpu_type}/${cpu_type}.h
 tm_d_file=${cpu_type}/${cpu_type}.h
+tm_rust_file=${cpu_type}/${cpu_type}.h
 if test -f ${srcdir}/config/${cpu_type}/${cpu_type}-protos.h
 then
 	tm_p_file=${cpu_type}/${cpu_type}-protos.h
 	tm_d_file="${tm_d_file} ${cpu_type}/${cpu_type}-protos.h"
+	tm_rust_file="${tm_rust_file} ${cpu_type}/${cpu_type}-protos.h"
 fi
 
 extra_modes=
@@ -3626,6 +3639,10 @@ if [ "$target_has_targetdm" = "no" ]; then
   d_target_objs="$d_target_objs default-d.o"
 fi
 
+if [ "$target_has_targetrustm" = "no" ]; then
+  rust_target_objs="$rust_target_objs default-rust.o"
+fi
+
 # Support for --with-cpu and related options (and a few unrelated options,
 # too).
 case ${with_cpu} in
diff --git a/gcc/config/default-rust.cc b/gcc/config/default-rust.cc
new file mode 100644
index 00000000000..a2754396e8c
--- /dev/null
+++ b/gcc/config/default-rust.cc
@@ -0,0 +1,26 @@
+/* Default Rust language target hooks initializer.
+   Copyright (C) 2020-2022 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/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "memmodel.h"
+#include "tm_rust.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+struct gcc_targetrustm targetrustm = TARGETRUSTM_INITIALIZER;
diff --git a/gcc/config/dragonfly.h b/gcc/config/dragonfly.h
index 0235e62681d..15209f987ab 100644
--- a/gcc/config/dragonfly.h
+++ b/gcc/config/dragonfly.h
@@ -35,6 +35,18 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     }                                       \
   while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in dragonflybsd.h - c++ undefines it and redefines it."
+/* TODO: ensure that this works correctly and the undef and redef reason is known */
+#endif
+#define TARGET_RUST_OS_INFO()                       \
+  do {                                              \
+    builtin_rust_info ("target_family", "unix");		\
+    builtin_rust_info ("target_os", "dragonfly");		\
+    builtin_rust_info ("target_vendor", "unknown"); \
+    builtin_rust_info ("target_env", "");			      \
+  } while (0)
+
 #undef  CPP_SPEC
 #define CPP_SPEC \
  "%(cpp_cpu) %(cpp_arch) %{posix:-D_POSIX_SOURCE}"
diff --git a/gcc/config/freebsd-spec.h b/gcc/config/freebsd-spec.h
index 594487829b5..d0c6ece315f 100644
--- a/gcc/config/freebsd-spec.h
+++ b/gcc/config/freebsd-spec.h
@@ -49,6 +49,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 /* Define the default FreeBSD-specific per-CPU hook code.  */
 #define FBSD_TARGET_CPU_CPP_BUILTINS() do {} while (0)
 
+#define FBSD_TARGET_RUST_OS_INFO()					\
+  do {					\
+    builtin_rust_info ("target_family", "unix");		\
+    builtin_rust_info ("target_os", "freebsd");		\
+    builtin_rust_info ("target_vendor", "unknown"); \
+    builtin_rust_info ("target_env", "");			      \
+    /*TODO: is default per-CPU hook code required here?*/ \
+  } while (0)
+
 /* Provide a CPP_SPEC appropriate for FreeBSD.  We just deal with the GCC 
    option `-posix', and PIC issues.  */
 
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index d89ee7dfc97..5748645673c 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -32,6 +32,11 @@ along with GCC; see the file COPYING3.  If not see
 #undef  TARGET_OS_CPP_BUILTINS
 #define TARGET_OS_CPP_BUILTINS() FBSD_TARGET_OS_CPP_BUILTINS()
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in freebsd.h - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO() FBSD_TARGET_RUST_OS_INFO()
+
 #undef  CPP_SPEC
 #define CPP_SPEC FBSD_CPP_SPEC
 
diff --git a/gcc/config/fuchsia.h b/gcc/config/fuchsia.h
index 0baf6f1f385..98dee35d823 100644
--- a/gcc/config/fuchsia.h
+++ b/gcc/config/fuchsia.h
@@ -68,3 +68,19 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (false)
 
+#ifndef EXTRA_TARGET_RUST_OS_INFO
+#define EXTRA_TARGET_RUST_OS_INFO()
+#endif
+
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in fuchsia.h - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {		\
+    builtin_rust_info ("target_family", "unix");		\
+	/*NOTE: target_family is subject to change if rustc decides to change it to non-unix*/ \
+    builtin_rust_info ("target_os", "fuchsia");		\
+    builtin_rust_info ("target_vendor", ""); \
+    builtin_rust_info ("target_env", "");			      \
+	EXTRA_TARGET_RUST_OS_INFO();		\
+  } while (0)
diff --git a/gcc/config/gnu.h b/gcc/config/gnu.h
index de2ead82be9..b0707148dd1 100644
--- a/gcc/config/gnu.h
+++ b/gcc/config/gnu.h
@@ -37,3 +37,15 @@ along with GCC.  If not, see <http://www.gnu.org/licenses/>.
 	builtin_version ("Hurd");		\
 	builtin_version ("CRuntime_Glibc");	\
     } while (0)
+
+#define GNU_USER_TARGET_RUST_OS_INFO()                                  \
+  do                                                                    \
+    { /*is this correct? or should os be "hurd"?*/                      \
+      builtin_rust_info ("target_family", "unix");                      \
+      builtin_rust_info ("target_os", "gnu");                           \
+      builtin_rust_info ("target_vendor", "unknown");                   \
+      builtin_rust_info ("target_env", "");                             \
+      /* TODO: is target_env required?*/                                \
+    }                                                                   \
+  while (0)
+
diff --git a/gcc/config/i386/crtdll.h b/gcc/config/i386/crtdll.h
index 75fede50fa0..5112e35389a 100644
--- a/gcc/config/i386/crtdll.h
+++ b/gcc/config/i386/crtdll.h
@@ -31,6 +31,18 @@ along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
+#ifdef EXTRA_TARGET_RUST_OS_INFO
+# error "EXTRA_TARGET_RUST_OS_INFO already defined in crtdll.h (i386) - c++ undefines it and redefines it."
+#endif
+#define EXTRA_TARGET_RUST_OS_INFO()					\
+  do {								\
+    builtin_rust_info ("target_family", "windows");	\
+    builtin_rust_info ("target_os", "windows");	\
+    builtin_rust_info ("target_vendor", "pc");	\
+    /*TODO: is this the right target_env? it says gnu tools up there, but env may change.*/ \
+    builtin_rust_info ("target_env", "gnu");	\
+  } while (0)
+
 #undef LIBGCC_SPEC
 #define LIBGCC_SPEC \
   "%{mthreads:-lmingwthrd} -lmingw32 -lgcc -lcoldname -libmingwex -lcrtdll"
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 45150458cc5..097592a4617 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -151,6 +151,11 @@ along with GCC; see the file COPYING3.  If not see
   }									\
   while (0)
 
+#define TARGET_RUST_OS_INFO()					\
+  do {									\
+  	EXTRA_TARGET_RUST_OS_INFO ();					\
+  } while (0)
+
 /* Get tree.cc to declare a target-specific specialization of
    merge_decl_attributes.  */
 #define TARGET_DLLIMPORT_DECL_ATTRIBUTES 1
diff --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h
index d06eda369cf..7657c2b3649 100644
--- a/gcc/config/i386/cygwin.h
+++ b/gcc/config/i386/cygwin.h
@@ -38,6 +38,16 @@ along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
+#define EXTRA_TARGET_RUST_OS_INFO()					\
+  do {								\
+    /*TODO: derived from llvm triple - rustc has no support for cygwin, but follows llvm triple*/ \
+    /*target_family is defined as unix due to posix-compliance, but this is subject to change*/ \
+    builtin_rust_info ("target_family", "unix");	\
+    builtin_rust_info ("target_os", "windows");	\
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "cygnus");	\
+  } while (0)
+
 #undef CPP_SPEC
 #define CPP_SPEC "%(cpp_cpu) %{posix:-D_POSIX_SOURCE} \
   %{!ansi:-Dunix} \
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index a55f6b2b874..3654a50d158 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -40,6 +40,16 @@ along with GCC; see the file COPYING3.  If not see
     darwin_cpp_builtins (pfile);		\
   } while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {								\
+    builtin_rust_info ("target_family", "unix");	\
+    /*TODO: rust actually has "macos", "ios", and "tvos" for darwin targets, but gcc seems to have no*/ \
+    /*current support for them, so assuming that target_os is always macos for now*/ \
+    builtin_rust_info ("target_os", "macos");	\
+    builtin_rust_info ("target_vendor", "apple");	\
+    builtin_rust_info ("target_env", "");	\
+  } while (0)
+
 #undef PTRDIFF_TYPE
 #define PTRDIFF_TYPE (TARGET_64BIT ? "long int" : "int")
 
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index 909821e953b..bc65b77470e 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -57,6 +57,15 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    /*rustc has no support for this, so values are taken from rusty-dos' djgpp github issue guesses*/ \
+    builtin_rust_info ("target_family", "windows");	\
+    builtin_rust_info ("target_os", "msdos");	\
+    builtin_rust_info ("target_vendor", "pc");	\
+    builtin_rust_info ("target_env", "djgpp");	\
+  } while (0)
+
 #undef CPP_SPEC
 #define CPP_SPEC "-remap %{posix:-D_POSIX_SOURCE}"
 
diff --git a/gcc/config/i386/gnu-user-common.h b/gcc/config/i386/gnu-user-common.h
index cab9be2bfb7..f95f8c047d6 100644
--- a/gcc/config/i386/gnu-user-common.h
+++ b/gcc/config/i386/gnu-user-common.h
@@ -36,6 +36,11 @@ along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
+#define TARGET_RUST_OS_INFO()				\
+  do {								\
+    GNU_USER_TARGET_RUST_OS_INFO();			\
+  } while (0)
+
 #undef CPP_SPEC
 #define CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
 
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index cf847751ac5..da360591e8f 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -281,6 +281,9 @@ extern void ix86_d_target_versions (void);
 extern void ix86_d_register_target_info (void);
 extern bool ix86_d_has_stdcall_convention (unsigned int *, unsigned int *);
 
+/* In i386-rust.cc  */
+extern void ix86_rust_target_cpu_info (void);
+
 /* In winnt.cc  */
 extern void i386_pe_unique_section (tree, int);
 extern void i386_pe_declare_function_type (FILE *, const char *, int);
diff --git a/gcc/config/i386/i386-rust.cc b/gcc/config/i386/i386-rust.cc
new file mode 100644
index 00000000000..1441a63f32c
--- /dev/null
+++ b/gcc/config/i386/i386-rust.cc
@@ -0,0 +1,501 @@
+/* Subroutines for the Rust front end on the x86 architecture.
+   Copyright (C) 2020-2022 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/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_CPU_INFO for x86 targets.  */
+
+void
+ix86_rust_target_cpu_info (void)
+{
+    if (TARGET_64BIT) {
+        rust_add_target_info("target_arch", "x86_64");
+
+        if (TARGET_X32) {
+            // this means it uses 32-bit pointers with 64-bit, basically (ILP32)
+            //rust_add_target_info("target_pointer_width", "32");
+            // TODO: may also change x86_64-...-linux-gnu to x86_64-...-linux-gnux32
+
+            // is this better than just putting in pointer width outside of if statement?
+
+            /* TODO: compared to base linux, may also need to change max_atomic_width to 64, add "-mx32"
+             * to pre-link args, make stack_probes true, make has_elf_tls false, make needs_plt true.
+             * Also, still target_endian is "little", target_c_int_width is "32", maybe steal data layout
+             * later from rustc spec, target_os is "linux", target_env is "gnu", target_vendor is "unknown"
+             * There is no rustc support for non-gnu/linux targets with ILP32. */
+        }
+    } else {
+        rust_add_target_info("target_arch", "x86");
+    }
+
+  // features officially "stabilised" in rustc
+  if (TARGET_MMX)
+    rust_add_target_info("target_feature", "mmx");
+  if (TARGET_SSE)
+    rust_add_target_info("target_feature", "sse");
+  if (TARGET_SSE2)
+    rust_add_target_info("target_feature", "sse2");
+  if (TARGET_SSE3)
+    rust_add_target_info("target_feature", "sse3");
+  if (TARGET_SSSE3)
+    rust_add_target_info("target_feature", "ssse3");
+  if (TARGET_SSE4_1)
+    rust_add_target_info("target_feature", "sse4.1");
+  if (TARGET_SSE4_2)
+    rust_add_target_info("target_feature", "sse4.2");
+  if (TARGET_AES)
+    rust_add_target_info("target_feature", "aes");
+  if (TARGET_SHA)
+    rust_add_target_info("target_feature", "sha");
+  if (TARGET_AVX)
+    rust_add_target_info("target_feature", "avx");
+  if (TARGET_AVX2)
+    rust_add_target_info("target_feature", "avx2");
+  if (TARGET_AVX512F)
+    rust_add_target_info("target_feature", "avx512f");
+  if (TARGET_AVX512ER)
+    rust_add_target_info("target_feature", "avx512er");
+  if (TARGET_AVX512CD)
+    rust_add_target_info("target_feature", "avx512cd");
+  if (TARGET_AVX512PF)
+    rust_add_target_info("target_feature", "avx512pf");
+  if (TARGET_AVX512DQ)
+    rust_add_target_info("target_feature", "avx512dq");
+  if (TARGET_AVX512BW)
+    rust_add_target_info("target_feature", "avx512bw");
+  if (TARGET_AVX512VL)
+    rust_add_target_info("target_feature", "avx512vl");
+  if (TARGET_AVX512VBMI)
+    rust_add_target_info("target_feature", "avx512vbmi");
+  if (TARGET_AVX512IFMA)
+    rust_add_target_info("target_feature", "avx512ifma");
+  if (TARGET_AVX512VPOPCNTDQ)
+    rust_add_target_info("target_feature", "avx512vpopcntdq");
+  if (TARGET_FMA)
+    rust_add_target_info("target_feature", "fma");
+  if (TARGET_RTM)
+    rust_add_target_info("target_feature", "rtm");
+  if (TARGET_SSE4A)
+    rust_add_target_info("target_feature", "sse4a");
+  if (TARGET_BMI) {
+    rust_add_target_info("target_feature", "bmi1");
+    rust_add_target_info("target_feature", "bmi");
+  }
+  if (TARGET_BMI2)
+    rust_add_target_info("target_feature", "bmi2");
+  if (TARGET_LZCNT)
+    rust_add_target_info("target_feature", "lzcnt");
+  if (TARGET_TBM)
+    rust_add_target_info("target_feature", "tbm");
+  if (TARGET_POPCNT)
+    rust_add_target_info("target_feature", "popcnt");
+  if (TARGET_RDRND) {
+    rust_add_target_info("target_feature", "rdrand");
+    rust_add_target_info("target_feature", "rdrnd");
+  }
+  if (TARGET_F16C)
+    rust_add_target_info("target_feature", "f16c");
+  if (TARGET_RDSEED)
+    rust_add_target_info("target_feature", "rdseed");
+  if (TARGET_ADX)
+    rust_add_target_info("target_feature", "adx");
+  if (TARGET_FXSR)
+    rust_add_target_info("target_feature", "fxsr");
+  if (TARGET_XSAVE)
+    rust_add_target_info("target_feature", "xsave");
+  if (TARGET_XSAVEOPT)
+    rust_add_target_info("target_feature", "xsaveopt");
+  if (TARGET_XSAVEC)
+    rust_add_target_info("target_feature", "xsavec");
+  if (TARGET_XSAVES)
+    rust_add_target_info("target_feature", "xsaves");
+  if (TARGET_VPCLMULQDQ) {
+    rust_add_target_info("target_feature", "pclmulqdq");
+    rust_add_target_info("target_feature", "vpclmulqdq");
+  }
+  if (TARGET_CMPXCHG16B)
+    rust_add_target_info("target_feature", "cmpxchg16b");
+  if (TARGET_MOVBE)
+    rust_add_target_info("target_feature", "movbe");
+
+  // features derived from llvm not yet in rustc:
+  if (TARGET_64BIT)
+    rust_add_target_info("target_feature", "64bit-mode");
+  else if (TARGET_CODE16)
+    rust_add_target_info("target_feature", "16bit-mode");
+  else
+    rust_add_target_info("target_feature", "32bit-mode");
+  
+  // TODO: assuming that the TARGET_80387 (which seems to mean "hard float") is also required for x87
+  if (TARGET_80387 && (ix86_fpmath & FPMATH_387) != 0)
+    rust_add_target_info("target_feature", "x87");
+
+  // nopl: hard-coded (as gcc doesn't technically have feature) to return true for cpu arches with it
+  // maybe refactor into switch if multiple options
+  bool hasNOPL = ix86_arch == PROCESSOR_PENTIUMPRO || ix86_arch == PROCESSOR_PENTIUM4 
+    || ix86_arch == PROCESSOR_NOCONA || ix86_arch == PROCESSOR_CORE2 || ix86_arch == PROCESSOR_NEHALEM 
+    || ix86_arch == PROCESSOR_BONNELL || ix86_arch == PROCESSOR_SILVERMONT 
+    || ix86_arch == PROCESSOR_GOLDMONT || ix86_arch == PROCESSOR_GOLDMONT_PLUS 
+    || ix86_arch == PROCESSOR_TREMONT || ix86_arch == PROCESSOR_SANDYBRIDGE 
+    || ix86_arch == PROCESSOR_HASWELL || ix86_arch == PROCESSOR_SKYLAKE 
+    || ix86_arch == PROCESSOR_SKYLAKE_AVX512 || ix86_arch == PROCESSOR_CANNONLAKE 
+    || ix86_arch == PROCESSOR_CASCADELAKE  || ix86_arch == PROCESSOR_COOPERLAKE 
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT || ix86_arch == PROCESSOR_ICELAKE_SERVER 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM 
+    || ix86_arch == PROCESSOR_AMDFAM10 || ix86_arch == PROCESSOR_BTVER1 || ix86_arch == PROCESSOR_BTVER2 
+    || ix86_arch == PROCESSOR_BDVER1 || ix86_arch == PROCESSOR_BDVER2 || ix86_arch == PROCESSOR_BDVER3 
+    || ix86_arch == PROCESSOR_BDVER4 || ix86_arch == PROCESSOR_ZNVER1 || ix86_arch == PROCESSOR_ZNVER2 
+    || ix86_arch == PROCESSOR_ATHLON || ix86_arch == PROCESSOR_K8; 
+  // this list should be exhaustive
+  if (hasNOPL)
+    rust_add_target_info("target_feature", "nopl");
+  if (TARGET_CMOVE)
+    rust_add_target_info("target_feature", "cmov");
+  if (TARGET_CMPXCHG8B)
+    rust_add_target_info("target_feature", "cx8");
+  if (TARGET_3DNOW)
+    rust_add_target_info("target_feature", "3dnow");
+  if (TARGET_3DNOW_A)
+    rust_add_target_info("target_feature", "3dnowa");
+  if (TARGET_64BIT)
+    rust_add_target_info("target_feature", "64bit");
+  if (TARGET_CMPXCHG16B)
+    rust_add_target_info("target_feature", "cx16");
+
+  bool hasSlowSHLD = ix86_arch == PROCESSOR_AMDFAM10 || ix86_arch == PROCESSOR_BTVER1 
+    || ix86_arch == PROCESSOR_BTVER2 || ix86_arch == PROCESSOR_BDVER1 || ix86_arch == PROCESSOR_BDVER2 
+    || ix86_arch == PROCESSOR_BDVER3 || ix86_arch == PROCESSOR_BDVER4 || ix86_arch == PROCESSOR_ZNVER1 
+    || ix86_arch == PROCESSOR_ZNVER2 || ix86_arch == PROCESSOR_ATHLON || ix86_arch == PROCESSOR_K8; 
+  // TODO: this is not ideal as it marks the baseline x86-64 CPU as having it - only AMD ones do
+  if (hasSlowSHLD)
+    rust_add_target_info("target_feature", "slow-shld");
+  if (ix86_arch == PROCESSOR_SILVERMONT)
+    rust_add_target_info("target_feature", "slow-pmulld");
+  if (ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM)
+    rust_add_target_info("target_feature", "slow-pmaddwd");
+
+  bool hasSlowUnaligned16 = ix86_arch == PROCESSOR_BONNELL || ix86_arch == PROCESSOR_GENERIC 
+    || ix86_arch == PROCESSOR_I386 || ix86_arch == PROCESSOR_I486 || ix86_arch == PROCESSOR_PENTIUM 
+    || ix86_arch == PROCESSOR_PENTIUMPRO || ix86_arch == PROCESSOR_PENTIUM4 
+    || ix86_arch == PROCESSOR_NOCONA || ix86_arch == PROCESSOR_CORE2 || ix86_arch == PROCESSOR_K6 
+    || ix86_arch == PROCESSOR_ATHLON || ix86_arch == PROCESSOR_K8 || ix86_arch == PROCESSOR_GEODE;
+  if (hasSlowUnaligned16)
+    rust_add_target_info("target_feature", "slow-unaligned-mem-16");
+  if (ix86_arch == PROCESSOR_SANDYBRIDGE)
+    rust_add_target_info("target_feature", "slow-unaligned-mem-32");
+  if (TARGET_PREFETCHWT1)
+    rust_add_target_info("target_feature", "prefetchwt1");
+  if (TARGET_AVX512VBMI2)
+    rust_add_target_info("target_feature", "avx512vbmi2");
+  if (TARGET_PKU)
+    rust_add_target_info("target_feature", "pku");
+  if (TARGET_AVX512VNNI)
+    rust_add_target_info("target_feature", "avx512vnni");
+  if (TARGET_AVX512BF16)
+    rust_add_target_info("target_feature", "avx512bf16");
+  if (TARGET_AVX512BITALG)
+    rust_add_target_info("target_feature", "avx512bitalg");
+  if (TARGET_AVX512VP2INTERSECT)
+    rust_add_target_info("target_feature", "avx512vp2intersect");
+  if (TARGET_PCLMUL)
+    rust_add_target_info("target_feature", "pclmul");
+  if (TARGET_GFNI)
+    rust_add_target_info("target_feature", "gfni");
+  if (TARGET_FMA4)
+    rust_add_target_info("target_feature", "fma4");
+  if (TARGET_XOP)
+    rust_add_target_info("target_feature", "xop");
+
+  // this is only enabled by choice in llvm, never by default - TODO determine if gcc enables it
+  // rust_add_target_info("target_feature", "sse-unaligned-mem");
+
+  if (TARGET_VAES)
+    rust_add_target_info("target_feature", "vaes");
+  if (TARGET_LWP)
+    rust_add_target_info("target_feature", "lwp");
+  if (TARGET_FSGSBASE)
+    rust_add_target_info("target_feature", "fsgsbase");
+  if (TARGET_SHSTK)
+    rust_add_target_info("target_feature", "shstk");
+  if (TARGET_PRFCHW)
+    rust_add_target_info("target_feature", "prfchw");
+  if (TARGET_SAHF) // would this be better as TARGET_USE_SAHF?
+    rust_add_target_info("target_feature", "sahf");
+  if (TARGET_MWAITX)
+    rust_add_target_info("target_feature", "mwaitx");
+  if (TARGET_CLZERO)
+    rust_add_target_info("target_feature", "clzero");
+  if (TARGET_CLDEMOTE)
+    rust_add_target_info("target_feature", "cldemote");
+  if (TARGET_PTWRITE)
+    rust_add_target_info("target_feature", "ptwrite");
+  // TODO: add amx-tile, amx-int8, amx-bf16 features when gcc supports them 
+
+  // TODO: can't find any gcc option relating to using LEA for adjusting stack pointer, so hardcoding
+  if (ix86_arch == PROCESSOR_BONNELL)
+    rust_add_target_info("target_feature", "lea-sp");
+
+  // TODO: confirm that this is what it actually refers to
+  if (TARGET_USE_8BIT_IDIV)
+    rust_add_target_info("target_feature", "idivl-to-divb");
+
+  /* TODO: can't find any gcc option corresponding to idivq-to-divl - does gcc perform this optimisation?
+   * if so, add that feature (use 32-bit divide for positive values less than 2^32) */
+  /* bool llvmHasSlowDivide64 = ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE 
+    || ix86_arch == PROCESSOR_BONNELL || ix86_arch == PROCESSOR_SILVERMONT || ix86_arch == PROCESSOR_KNL 
+    || ix86_arch == PROCESSOR_KNM || ix86_arch == PROCESSOR_K8;*/
+
+  if (TARGET_PAD_SHORT_FUNCTION)
+    rust_add_target_info("target_feature", "pad-short-functions");
+
+  // TODO: gcc seems to not record whether INVPCID exists, so basing it on llvm
+  bool hasINVPCID = ix86_arch == PROCESSOR_HASWELL || ix86_arch == PROCESSOR_SKYLAKE 
+    || ix86_arch == PROCESSOR_SKYLAKE_AVX512 || ix86_arch == PROCESSOR_CANNONLAKE 
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT || ix86_arch == PROCESSOR_ICELAKE_SERVER 
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_TIGERLAKE 
+    || ix86_arch == PROCESSOR_COOPERLAKE; 
+  if (hasINVPCID)
+    rust_add_target_info("target_feature", "invpcid");
+  if (TARGET_SGX)
+    rust_add_target_info("target_feature", "sgx");
+  if (TARGET_CLFLUSHOPT)
+    rust_add_target_info("target_feature", "clflushopt");
+  if (TARGET_CLWB)
+    rust_add_target_info("target_feature", "clwb");
+  if (TARGET_WBNOINVD)
+    rust_add_target_info("target_feature", "wbnoinvd");
+  if (TARGET_RDPID)
+    rust_add_target_info("target_feature", "rdpid");
+  if (TARGET_WAITPKG)
+    rust_add_target_info("target_feature", "waitpkg");
+  if (TARGET_ENQCMD)
+    rust_add_target_info("target_feature", "enqcmd");
+
+  // these are only enabled by choice in llvm, never by default - TODO determine if gcc supports them
+  // rust_add_target_info("target_feature", "serialize");
+  // rust_add_target_info("target_feature", "tsxldtrk");
+
+  // TODO: gcc seems to not record whether to avoid memory operanded instructions, so basing it on llvm
+  bool hasSlowTwoMemOps = ix86_arch == PROCESSOR_BONNELL || ix86_arch == PROCESSOR_SILVERMONT 
+    || ix86_arch == PROCESSOR_GOLDMONT || ix86_arch == PROCESSOR_GOLDMONT_PLUS 
+    || ix86_arch == PROCESSOR_TREMONT || ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM; 
+  if (hasSlowTwoMemOps)
+    rust_add_target_info("target_feature", "slow-two-mem-ops");
+
+  // TODO: gcc seems to not record whether LEA needs input at AG stage, so basing it on llvm
+  // TODO: maybe something to do with X86_TUNE_OPT_AGU?
+  if (ix86_arch == PROCESSOR_BONNELL)
+    rust_add_target_info("target_feature", "lea-uses-ag");
+
+  // TODO: gcc seems to not record whether LEA with certain arguments is slow, so basing it on llvm
+  // TODO: maybe TARGET_AVOID_LEA_FOR_ADDR has something to do with it?
+  bool hasSlowLEA = ix86_arch == PROCESSOR_SILVERMONT || ix86_arch == PROCESSOR_GOLDMONT 
+    || ix86_arch == PROCESSOR_GOLDMONT_PLUS || ix86_arch == PROCESSOR_TREMONT;
+  if (hasSlowLEA)
+    rust_add_target_info("target_feature", "slow-lea");
+  
+  // TODO: gcc seems to not record whether LEA with 3 ops or certain regs is slow, so basing it on llvm
+  // TODO: maybe TARGET_AVOID_LEA_FOR_ADDR has something to do with it?
+  bool hasSlow3OpsLEA = ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE 
+    || ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM || ix86_arch == PROCESSOR_K8; 
+  if (hasSlow3OpsLEA)
+    rust_add_target_info("target_feature", "slow-3ops-lea");
+
+  // TODO: assuming that this is equivalent option - it strictly doesn't cover same cpus
+  if (!TARGET_USE_INCDEC)
+    rust_add_target_info("target_feature", "slow-incdec");
+  // TODO: assuming that this mask actually refers to "hard float" and not x87 specifically
+  if (!TARGET_80387)
+    rust_add_target_info("target_feature", "soft-float");
+
+  // TODO: gcc seems to not record if LZCNT/TZCNT has false deps on dest register, so basing it on llvm
+  if (ix86_arch == PROCESSOR_HASWELL)
+    rust_add_target_info("target_feature", "false-deps-lzcnt-tzcnt");
+
+  if (TARGET_PCONFIG)
+    rust_add_target_info("target_feature", "pconfig");
+
+  // TODO: gcc seems to not record if variable-mask shuffles are fast, so basing it on llvm
+  bool hasFastVariableShuffle = ix86_arch == PROCESSOR_HASWELL || ix86_arch == PROCESSOR_SKYLAKE 
+    || ix86_arch == PROCESSOR_SKYLAKE_AVX512 || ix86_arch == PROCESSOR_CANNONLAKE 
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT || ix86_arch == PROCESSOR_ICELAKE_SERVER 
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_TIGERLAKE 
+    || ix86_arch == PROCESSOR_COOPERLAKE; 
+  if (hasFastVariableShuffle)
+    rust_add_target_info("target_feature", "fast-variable-shuffle");
+
+  // TODO: ensure that this actually refers to the right thing - difference in gcc and llvm description
+  if (TARGET_VZEROUPPER)
+    rust_add_target_info("target_feature", "vzeroupper");
+
+  // option based on llvm arch analysis as gcc tuning costs seem to indicate a different result
+  bool hasFastScalarFSQRT = ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE;
+  if (hasFastScalarFSQRT)
+    rust_add_target_info("target_feature", "fast-scalar-fsqrt");
+
+  // option also based on llvm arch analysis 
+  bool hasFastVectorFSQRT = ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE;
+  if (hasFastVectorFSQRT)
+    rust_add_target_info("target_feature", "fast-vector-fsqrt");
+
+  bool hasFastLZCNT = ix86_arch == PROCESSOR_BTVER2 || ix86_arch == PROCESSOR_ZNVER1 
+    || ix86_arch == PROCESSOR_ZNVER2;
+  if (hasFastLZCNT)
+    rust_add_target_info("target_feature", "fast-lzcnt");
+
+  if (ix86_arch == PROCESSOR_SILVERMONT)
+    rust_add_target_info("target_feature", "fast-7bytenop");
+
+  bool hasFast11ByteNOP = ix86_arch == PROCESSOR_BDVER1 || ix86_arch == PROCESSOR_BDVER2 
+    || ix86_arch == PROCESSOR_BDVER3 || ix86_arch == PROCESSOR_BDVER4;
+  if (hasFast11ByteNOP)
+    rust_add_target_info("target_feature", "fast-11bytenop");
+
+  bool hasFast15ByteNOP = ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE 
+    || ix86_arch == PROCESSOR_BTVER1 || ix86_arch == PROCESSOR_BTVER2
+    || ix86_arch == PROCESSOR_ZNVER1 || ix86_arch == PROCESSOR_ZNVER2;
+  if (hasFast15ByteNOP)
+    rust_add_target_info("target_feature", "fast-15bytenop");
+
+  bool hasFastSHLDRotate = ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE;
+  if (hasFastSHLDRotate)
+    rust_add_target_info("target_feature", "fast-shld-rotate");
+
+  bool hasERMSB = ix86_arch == PROCESSOR_HASWELL || ix86_arch == PROCESSOR_SKYLAKE 
+    || ix86_arch == PROCESSOR_SKYLAKE_AVX512 || ix86_arch == PROCESSOR_CANNONLAKE 
+    || ix86_arch == PROCESSOR_ICELAKE_CLIENT || ix86_arch == PROCESSOR_ICELAKE_SERVER 
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_TIGERLAKE 
+    || ix86_arch == PROCESSOR_COOPERLAKE; 
+  if (hasERMSB)
+    rust_add_target_info("target_feature", "ermsbd");
+
+  // TODO: may exist in gcc as tune macros, but not sure, so based on llvm arches
+  bool hasBranchFusion = ix86_arch == PROCESSOR_BDVER1 || ix86_arch == PROCESSOR_BDVER2 
+    || ix86_arch == PROCESSOR_BDVER3 || ix86_arch == PROCESSOR_BDVER4 || ix86_arch == PROCESSOR_ZNVER1 
+    || ix86_arch == PROCESSOR_ZNVER2;
+  if (hasBranchFusion)
+    rust_add_target_info("target_feature", "branchfusion");
+
+  // TODO: again, may exist as tune macros, but again based on llvm arches
+  bool hasMacroFusion = ix86_arch == PROCESSOR_CORE2 || ix86_arch == PROCESSOR_NEHALEM 
+    || ix86_arch == PROCESSOR_SANDYBRIDGE || ix86_arch == PROCESSOR_HASWELL 
+    || ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_CASCADELAKE 
+    || ix86_arch == PROCESSOR_TIGERLAKE || ix86_arch == PROCESSOR_COOPERLAKE || ix86_arch == PROCESSOR_K8;
+  if (hasMacroFusion)
+    rust_add_target_info("target_feature", "macrofusion");
+
+  // TODO: is this equivalent to TARGET_USE_GATHER?
+  bool hasFastGather = ix86_arch == PROCESSOR_SKYLAKE || ix86_arch == PROCESSOR_SKYLAKE_AVX512 
+    || ix86_arch == PROCESSOR_CASCADELAKE || ix86_arch == PROCESSOR_COOPERLAKE 
+    || ix86_arch == PROCESSOR_CANNONLAKE || ix86_arch == PROCESSOR_ICELAKE_CLIENT 
+    || ix86_arch == PROCESSOR_ICELAKE_SERVER || ix86_arch == PROCESSOR_TIGERLAKE 
+    || ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM;
+  if (hasFastGather)
+    rust_add_target_info("target_feature", "fast-gather");
+
+  if (TARGET_PREFER_AVX128)
+    rust_add_target_info("target_feature", "prefer-128-bit");
+  if (TARGET_PREFER_AVX256)
+    rust_add_target_info("target_feature", "prefer-256-bit");
+
+  bool preferMaskRegisters = ix86_arch == PROCESSOR_KNL || ix86_arch == PROCESSOR_KNM;
+  if (preferMaskRegisters)
+    rust_add_target_info("target_feature", "prefer-mask-registers");
+
+  /* TODO: add retpoline-indirect-calls, retpoline-indirect-branches, retpoline, retpoline-external-thunk, 
+   * lvi-cfi (LVI control flow integrity), seses (speculative execution side-effect suppression)
+   * lvi-load-hardening if gcc gets support */
+
+  if (TARGET_MOVDIRI)
+    rust_add_target_info("target_feature", "movdiri");
+  if (TARGET_MOVDIR64B)
+    rust_add_target_info("target_feature", "movdir64b");
+
+  bool hasFastBEXTR = ix86_arch == PROCESSOR_BTVER2 || ix86_arch == PROCESSOR_BDVER2 
+    || ix86_arch == PROCESSOR_BDVER3 || ix86_arch == PROCESSOR_BDVER4 || ix86_arch == PROCESSOR_ZNVER1 
+    || ix86_arch == PROCESSOR_ZNVER2;
+  if (hasFastBEXTR)
+    rust_add_target_info("target_feature", "fast-bextr");
+
+  if (ix86_arch == PROCESSOR_BTVER2)
+    rust_add_target_info("target_feature", "fast-hops");
+
+  bool hasFastScalarShiftMasks = ix86_arch == PROCESSOR_AMDFAM10 || ix86_arch == PROCESSOR_BTVER1 
+    || ix86_arch == PROCESSOR_BTVER2 || ix86_arch == PROCESSOR_BDVER1 || ix86_arch == PROCESSOR_BDVER2 
+    || ix86_arch == PROCESSOR_BDVER3 || ix86_arch == PROCESSOR_BDVER4 || ix86_arch == PROCESSOR_ZNVER1 
+    || ix86_arch == PROCESSOR_ZNVER2 || ix86_arch == PROCESSOR_K8;
+  if (hasFastScalarShiftMasks)
+    rust_add_target_info("target_feature", "fast-scalar-shift-masks");
+
+  bool hasFastVectorShiftMasks = ix86_arch == PROCESSOR_BTVER1 || ix86_arch == PROCESSOR_BTVER2;
+  if (hasFastVectorShiftMasks)
+    rust_add_target_info("target_feature", "fast-vector-shift-masks");
+
+  bool useGoldmontDivSqrtCosts = ix86_arch == PROCESSOR_GOLDMONT || ix86_arch == PROCESSOR_GOLDMONT_PLUS 
+    || ix86_arch == PROCESSOR_TREMONT;
+  if (useGoldmontDivSqrtCosts)
+    rust_add_target_info("target_feature", "use-glm-div-sqrt-costs");
+  
+  // TODO: determine if gcc supports alias analysis (in which case "use-aa" is defined)
+
+  // features not supported by llvm but important enough for c frontend to define macros for
+  /*if (TARGET_AVX5124VNNIW)
+    rust_add_target_info("target_feature", "avx5124vnniw");
+  if (TARGET_AVX5124FMAPS)
+    rust_add_target_info("target_feature", "avx5124fmaps");
+  if (TARGET_ABM)
+    rust_add_target_info("target_feature", "abm");
+  if ((ix86_fpmath & FPMATH_SSE) && TARGET_SSE)
+    ; //def_or_undef (parse_in, "__SSE_MATH__");
+  if ((ix86_fpmath & FPMATH_SSE) && TARGET_SSE2)
+    ; //def_or_undef (parse_in, "__SSE2_MATH__");
+  if (TARGET_MMX_WITH_SSE)
+    ; //def_or_undef (parse_in, "__MMX_WITH_SSE__");
+  if (TARGET_IAMCU)
+    rust_add_target_info("target_feature", "iamcu");*/
+}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index f16df633e84..93d5de5cd61 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -613,6 +613,9 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
 #define TARGET_D_REGISTER_CPU_TARGET_INFO ix86_d_register_target_info
 #define TARGET_D_HAS_STDCALL_CONVENTION ix86_d_has_stdcall_convention
 
+/* Target CPU info for Rust.  */
+#define TARGET_RUST_CPU_INFO ix86_rust_target_cpu_info 
+
 #ifndef CC1_SPEC
 #define CC1_SPEC "%(cc1_cpu) "
 #endif
diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h
index efa7fb2072c..25aa5f368f2 100644
--- a/gcc/config/i386/linux-common.h
+++ b/gcc/config/i386/linux-common.h
@@ -30,6 +30,23 @@ along with GCC; see the file COPYING3.  If not see
 #define EXTRA_TARGET_D_OS_VERSIONS()		\
   ANDROID_TARGET_D_OS_VERSIONS();
 
+#define EXTRA_TARGET_RUST_OS_INFO()		\
+  ANDROID_TARGET_RUST_OS_INFO();
+// TODO: decide on whether following c frontend style or d one - leaning towards c
+
+
+/*#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in linux-common.h (i386) - c++ undefines it and redefines it."
+# error "note that this above error (linux-common-i386) is expected due to already defining EXTRA_TARGET stuff"
+#endif*/
+/* This is previously defined in gnu-user-common.h, but has no linux-specific info.  */
+#undef TARGET_RUST_OS_INFO 
+#define TARGET_RUST_OS_INFO()               \
+  do {                                      \
+    GNU_USER_TARGET_RUST_OS_INFO();         \
+    ANDROID_TARGET_RUST_OS_INFO();          \
+  } while (0)
+
 #undef CC1_SPEC
 #define CC1_SPEC \
   LINUX_OR_ANDROID_CC (GNU_USER_TARGET_CC1_SPEC, \
diff --git a/gcc/config/i386/lynx.h b/gcc/config/i386/lynx.h
index baa62c14986..ecc10264dde 100644
--- a/gcc/config/i386/lynx.h
+++ b/gcc/config/i386/lynx.h
@@ -25,6 +25,15 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    /*TODO: not supported by rustc and so subject to change - based on llvm triple*/ \
+    builtin_rust_info ("target_family", "unix");	\
+    builtin_rust_info ("target_os", "lynxos");	\
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "");	\
+  } while (0)
+
 /* The svr4 ABI for the i386 says that records and unions are returned
    in memory.  */
 
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index d3ca0cd0279..e5381de9f90 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -65,6 +65,14 @@ along with GCC; see the file COPYING3.  If not see
     }								\
   while (0)
 
+#define EXTRA_TARGET_RUST_OS_INFO()					\
+  do {								\
+    builtin_rust_info ("target_family", "windows");	\
+    builtin_rust_info ("target_os", "windows");	\
+    builtin_rust_info ("target_vendor", "pc");	\
+    builtin_rust_info ("target_env", "gnu");	\
+  } while (0)
+
 #ifndef TARGET_USE_PTHREAD_BY_DEFAULT
 #define SPEC_PTHREAD1 "pthread"
 #define SPEC_PTHREAD2 "!no-pthread"
diff --git a/gcc/config/i386/netbsd-elf.h b/gcc/config/i386/netbsd-elf.h
index b1d7d484ce7..aa60438ea77 100644
--- a/gcc/config/i386/netbsd-elf.h
+++ b/gcc/config/i386/netbsd-elf.h
@@ -26,6 +26,11 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    NETBSD_TARGET_RUST_OS_INFO();		\
+  } while (0)
+
 
 /* Extra specs needed for NetBSD/i386 ELF.  */
 
diff --git a/gcc/config/i386/netbsd64.h b/gcc/config/i386/netbsd64.h
index 656fd45af6f..7eba96b9ec0 100644
--- a/gcc/config/i386/netbsd64.h
+++ b/gcc/config/i386/netbsd64.h
@@ -26,6 +26,11 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    NETBSD_TARGET_RUST_OS_INFO();		\
+  } while (0)
+
 
 /* Extra specs needed for NetBSD/x86-64 ELF.  */
 
diff --git a/gcc/config/i386/nto.h b/gcc/config/i386/nto.h
index 5df300918d9..6b92d5924be 100644
--- a/gcc/config/i386/nto.h
+++ b/gcc/config/i386/nto.h
@@ -36,6 +36,18 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in nto.h (i386) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    /*TODO: not supported by rustc and so subject to change - based on triple found online*/ \
+    builtin_rust_info ("target_family", "unix");	\
+    builtin_rust_info ("target_os", "nto");	\
+    builtin_rust_info ("target_vendor", "pc");	\
+    builtin_rust_info ("target_env", "qnx");	\
+  } while (0)
+
 #undef THREAD_MODEL_SPEC
 #define THREAD_MODEL_SPEC "posix"
 
diff --git a/gcc/config/i386/openbsdelf.h b/gcc/config/i386/openbsdelf.h
index 2176e79495c..060ae0f6afa 100644
--- a/gcc/config/i386/openbsdelf.h
+++ b/gcc/config/i386/openbsdelf.h
@@ -25,6 +25,11 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    OPENBSD_TARGET_RUST_OS_INFO();		\
+  } while (0)
+
 #undef DBX_REGISTER_NUMBER
 #define DBX_REGISTER_NUMBER(n) \
   (TARGET_64BIT ? dbx64_register_map[n] : svr4_dbx_register_map[n])
diff --git a/gcc/config/i386/rdos.h b/gcc/config/i386/rdos.h
index 9549977cbf8..c185d0efc2f 100644
--- a/gcc/config/i386/rdos.h
+++ b/gcc/config/i386/rdos.h
@@ -37,3 +37,14 @@ along with GCC; see the file COPYING3.  If not see
       builtin_assert ("system=rdos");		\
     }						\
   while (0)
+
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+    /*TODO: not supported by rustc and so subject to change - based on triple found online*/ \
+    /*this seems to not refer to the 70s Data General RDOS, but one partly compatible with win32*/ \
+    /*as such, target_family could be windows*/ \
+    builtin_rust_info ("target_family", "");	\
+    builtin_rust_info ("target_os", "rdos");	\
+    builtin_rust_info ("target_vendor", "pc");	\
+    builtin_rust_info ("target_env", "");	\
+  } while (0)
diff --git a/gcc/config/i386/rtemself.h b/gcc/config/i386/rtemself.h
index a6035ffdad1..2f1cbdaf23f 100644
--- a/gcc/config/i386/rtemself.h
+++ b/gcc/config/i386/rtemself.h
@@ -33,3 +33,13 @@
 	builtin_assert ("system=rtems");	\
     }						\
   while (0)
+
+#define TARGET_RUST_OS_INFO()		\
+  do {		\
+    /*note: as far as I know, rustc has no supported for rtems, so this is just guessed*/ \
+    /*everything is subject to change, especially target_env and target_family*/ \
+    builtin_rust_info ("target_family", "unix");			\
+    builtin_rust_info ("target_os", "rtems");			\
+    builtin_rust_info ("target_vendor", "unknown");			\
+    builtin_rust_info ("target_env", "");			\
+  } while (0)
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index 4e2a0efc615..61ddfcab6ba 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -46,6 +46,10 @@ i386-d.o: $(srcdir)/config/i386/i386-d.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+i386-rust.o: $(srcdir)/config/i386/i386-rust.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 i386-options.o: $(srcdir)/config/i386/i386-options.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
diff --git a/gcc/config/i386/vxworks.h b/gcc/config/i386/vxworks.h
index 3b8eb6f3a59..af1f42abcb3 100644
--- a/gcc/config/i386/vxworks.h
+++ b/gcc/config/i386/vxworks.h
@@ -113,6 +113,11 @@ along with GCC; see the file COPYING3.  If not see
     }							\
   while (0)
 
+#define TARGET_RUST_OS_INFO()			\
+  do {							\
+    VXWORKS_TARGET_RUST_OS_INFO();			\
+  } while (0)
+
 #undef  CPP_SPEC
 #define CPP_SPEC VXWORKS_ADDITIONAL_CPP_SPEC
 #undef  CC1_SPEC
diff --git a/gcc/config/kfreebsd-gnu.h b/gcc/config/kfreebsd-gnu.h
index f74a627bc43..d8892bf4bc5 100644
--- a/gcc/config/kfreebsd-gnu.h
+++ b/gcc/config/kfreebsd-gnu.h
@@ -35,6 +35,14 @@ along with GCC; see the file COPYING3.  If not see
 	builtin_version ("CRuntime_Glibc");	\
     } while (0)
 
+#define GNU_USER_TARGET_RUST_OS_INFO()		\
+    do {					\
+  builtin_rust_info ("target_family", "unix");			\
+  builtin_rust_info ("target_os", "kfreebsd");			\
+  builtin_rust_info ("target_vendor", "unknown");			\
+  builtin_rust_info ("target_env", "gnu");			\
+    } while (0)
+
 #define GNU_USER_DYNAMIC_LINKER        GLIBC_DYNAMIC_LINKER
 #define GNU_USER_DYNAMIC_LINKER32      GLIBC_DYNAMIC_LINKER32
 #define GNU_USER_DYNAMIC_LINKER64      GLIBC_DYNAMIC_LINKER64
diff --git a/gcc/config/kopensolaris-gnu.h b/gcc/config/kopensolaris-gnu.h
index 8379f960b8b..bdeb29a635d 100644
--- a/gcc/config/kopensolaris-gnu.h
+++ b/gcc/config/kopensolaris-gnu.h
@@ -36,5 +36,17 @@ along with GCC; see the file COPYING3.  If not see
 	builtin_version ("CRuntime_Glibc");	\
     } while (0)
 
+#ifdef GNU_USER_TARGET_RUST_OS_INFO
+# error # error "TARGET_RUST_OS_INFO already defined in kopensolaris-gnu.h - c++ undefines it and redefines it."
+#endif
+#define GNU_USER_TARGET_RUST_OS_INFO()		\
+    do {					\
+  builtin_rust_info ("target_family", "unix");			\
+  builtin_rust_info ("target_os", "kopensolaris");			\
+  /*the target_os is maybe not right but i can't find any better atm*/ \
+  builtin_rust_info ("target_vendor", "unknown");			\
+  builtin_rust_info ("target_env", "gnu");			\
+    } while (0)
+
 #undef GNU_USER_DYNAMIC_LINKER
 #define GNU_USER_DYNAMIC_LINKER "/lib/ld.so.1"
diff --git a/gcc/config/linux-android.h b/gcc/config/linux-android.h
index cf340660adb..3d5548e3eb3 100644
--- a/gcc/config/linux-android.h
+++ b/gcc/config/linux-android.h
@@ -31,6 +31,18 @@
 	  builtin_version ("Android");				\
     } while (0)
 
+#define ANDROID_TARGET_RUST_OS_INFO()				\
+    do {							\
+  if (TARGET_ANDROID)	{				\
+    builtin_rust_info ("target_family", "unix");				\
+    builtin_rust_info ("target_os", "android");				\
+    builtin_rust_info ("target_vendor", "unknown");				\
+    builtin_rust_info ("target_env", "");				\
+  } else {				\
+    builtin_rust_info ("target_os", "linux");				\
+  }	/*this else is required if I'm intepreting structure of defines correctly*/			\
+    } while (0)
+
 #if ANDROID_DEFAULT
 # define NOANDROID "mno-android"
 #else
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 74f70793d90..13a714b9e81 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -71,6 +71,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 	  builtin_version ("CRuntime_Musl");			\
     } while (0)
 
+#define GNU_USER_TARGET_RUST_OS_INFO()				\
+    do {							\
+  builtin_rust_info ("target_family", "unix");			\
+  builtin_rust_info ("target_vendor", "unknown");			\
+  /*is there way of determining target_os and target_env here since could also be android?*/		\
+  /*target_vendor may not be "unknown" - FIXME ensure it is*/  \
+  if (OPTION_GLIBC)			\
+      builtin_rust_info ("target_env", "gnu");			\
+  else if (OPTION_MUSL)			\
+      builtin_rust_info ("target_env", "musl");			\
+  else /*TODO: determine if bionic and uclibc are considered to be different envs in rustc*/ \
+      builtin_rust_info ("target_env", "");			\
+    } while (0)
+
 /* Determine which dynamic linker to use depending on whether GLIBC or
    uClibc or Bionic or musl is the default C library and whether
    -muclibc or -mglibc or -mbionic or -mmusl has been passed to change
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
index 9e46a0fff02..8e6bd0a2675 100644
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -29,6 +29,15 @@ along with GCC; see the file COPYING3.  If not see
     }						\
   while (0)
 
+/* TARGET_RUST_OS_INFO() common to all NetBSD targets.  */
+#define NETBSD_TARGET_RUST_OS_INFO()		\
+  do {		\
+    builtin_rust_info ("target_family", "unix");			\
+    builtin_rust_info ("target_os", "netbsd");			\
+    builtin_rust_info ("target_vendor", "unknown");			\
+    builtin_rust_info ("target_env", "");			\
+  } while (0)
+
 /* CPP_SPEC parts common to all NetBSD targets.  */
 #define NETBSD_CPP_SPEC				\
   "%{posix:-D_POSIX_SOURCE} \
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 54be2225492..d91e1e9d8d7 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -102,6 +102,14 @@ while (0)
     }						\
   while (0)
 
+#define OPENBSD_TARGET_RUST_OS_INFO()		\
+  do {		\
+    builtin_rust_info ("target_family", "unix");		\
+    builtin_rust_info ("target_os", "openbsd");		\
+    builtin_rust_info ("target_vendor", "unknown"); \
+    builtin_rust_info ("target_env", "");			      \
+  } while(0)
+
 /* CPP_SPEC appropriate for OpenBSD. We deal with -posix and -pthread.
    XXX the way threads are handled currently is not very satisfying,
    since all code must be compiled with -pthread to work. 
diff --git a/gcc/config/phoenix.h b/gcc/config/phoenix.h
index d9eef357370..e9dbbd0b2ae 100644
--- a/gcc/config/phoenix.h
+++ b/gcc/config/phoenix.h
@@ -26,6 +26,18 @@ along with GCC; see the file COPYING3.  If not see
       builtin_assert ("system=unix");      \
     } while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in phoenix.h - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()                       \
+  do {                                              \
+    builtin_rust_info ("target_family", "unix");		\
+    builtin_rust_info ("target_os", "phoenix");		  \
+    builtin_rust_info ("target_vendor", "unknown"); \
+    builtin_rust_info ("target_env", "");			      \
+    /*TODO: ensure these values are correct*/       \
+  } while(0)
+
 #define STD_LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
 
 /* This will prevent selecting 'unsigned long int' instead of 'unsigned int' as 'uint32_t' in stdint-newlib.h. */
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index e22c70c45ae..8cf2164c284 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -124,6 +124,16 @@ along with GCC; see the file COPYING3.  If not see
     solaris_override_options ();			\
   } while (0)
 
+#define EXTRA_TARGET_RUST_OS_INFO()
+#define TARGET_RUST_OS_INFO()			\
+  do {			\
+    builtin_rust_info ("target_family", "unix");			\
+    builtin_rust_info ("target_os", "solaris");			\
+    builtin_rust_info ("target_vendor", "sun");			\
+    builtin_rust_info ("target_env", "");			\
+    EXTRA_TARGET_RUST_OS_INFO();			\
+  } while (0)
+
 #if DEFAULT_ARCH32_P
 #define MULTILIB_DEFAULTS { "m32" }
 #else
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index 6a5f2f8f2ec..4811b428455 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -337,6 +337,14 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
     }									\
   while (0)
 
+#define VXWORKS_TARGET_RUST_OS_INFO()					\
+  do {					\
+    builtin_rust_info ("target_family", "unix");			\
+    builtin_rust_info ("target_os", "vxworks");			\
+    builtin_rust_info ("target_vendor", "wrs");			\
+    builtin_rust_info ("target_env", "gnu");			\
+  } while (0)
+
 /* For specific CPU macro definitions expected by the system headers,
    different versions of VxWorks expect different forms of macros,
    such as "_VX_CPU=..." on Vx7 and some variants of Vx6, or "CPU=..."
diff --git a/gcc/config/vxworksae.h b/gcc/config/vxworksae.h
index 0cc45467ab8..dc1dbe15ff1 100644
--- a/gcc/config/vxworksae.h
+++ b/gcc/config/vxworksae.h
@@ -77,6 +77,15 @@ along with GCC; see the file COPYING3.  If not see
     }                                                                   \
   while (0)
 
+#define VXWORKS_TARGET_RUST_OS_INFO()					\
+  do {					\
+    builtin_rust_info ("target_family", "unix");			\
+    builtin_rust_info ("target_os", "vxworks");			\
+    builtin_rust_info ("target_vendor", "wrs");			\
+    builtin_rust_info ("target_env", "gnu");			\
+    /*is env correct? vxworks.h implies that this might not come with a gnu toolchain*/ \
+  } while (0)
+
 /* Do VxWorks-specific parts of TARGET_OPTION_OVERRIDE.  */
 
 /* None of the VxWorks AE/653/MILS ports to date has native TLS support.  */
diff --git a/gcc/configure b/gcc/configure
index 62872d132ea..44cab9654d9 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -644,6 +644,7 @@ ISLLIBS
 GMPINC
 GMPLIBS
 target_cpu_default
+rust_target_objs
 d_target_objs
 fortran_target_objs
 cxx_target_objs
@@ -652,6 +653,8 @@ use_gcc_stdint
 xm_defines
 xm_include_list
 xm_file_list
+tm_rust_include_list
+tm_rust_file_list
 tm_d_include_list
 tm_d_file_list
 tm_p_include_list
@@ -13010,6 +13013,7 @@ fi
 tm_file="${tm_file} defaults.h"
 tm_p_file="${tm_p_file} tm-preds.h"
 tm_d_file="${tm_d_file} defaults.h"
+tm_rust_file="${tm_rust_file} defaults.h"
 host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
 build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
 # We don't want ansidecl.h in target files, write code there in ISO/GNU C.
@@ -13418,6 +13422,21 @@ for f in $tm_d_file; do
   esac
 done
 
+tm_rust_file_list=
+tm_rust_include_list="options.h insn-constants.h"
+for f in $tm_rust_file; do
+  case $f in
+    defaults.h )
+       tm_rust_file_list="${tm_rust_file_list} \$(srcdir)/$f"
+       tm_rust_include_list="${tm_rust_include_list} $f"
+       ;;
+    * )
+       tm_rust_file_list="${tm_rust_file_list} \$(srcdir)/config/$f"
+       tm_rust_include_list="${tm_rust_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 446747311a6..c54e9f40796 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2114,6 +2114,7 @@ AC_SUBST(HAVE_AUTO_BUILD)
 tm_file="${tm_file} defaults.h"
 tm_p_file="${tm_p_file} tm-preds.h"
 tm_d_file="${tm_d_file} defaults.h"
+tm_rust_file="${tm_rust_file} defaults.h"
 host_xm_file="auto-host.h ansidecl.h ${host_xm_file}"
 build_xm_file="${build_auto} ansidecl.h ${build_xm_file}"
 # We don't want ansidecl.h in target files, write code there in ISO/GNU C.
@@ -2371,6 +2372,21 @@ for f in $tm_d_file; do
   esac
 done
 
+tm_rust_file_list=
+tm_rust_include_list="options.h insn-constants.h"
+for f in $tm_rust_file; do
+  case $f in
+    defaults.h )
+       tm_rust_file_list="${tm_rust_file_list} \$(srcdir)/$f"
+       tm_rust_include_list="${tm_rust_include_list} $f"
+       ;;
+    * )
+       tm_rust_file_list="${tm_rust_file_list} \$(srcdir)/config/$f"
+       tm_rust_include_list="${tm_rust_include_list} config/$f"
+       ;;
+  esac
+done
+
 xm_file_list=
 xm_include_list=
 for f in $xm_file; do
@@ -7350,6 +7366,8 @@ AC_SUBST(tm_p_file_list)
 AC_SUBST(tm_p_include_list)
 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(xm_file_list)
 AC_SUBST(xm_include_list)
 AC_SUBST(xm_defines)
@@ -7358,6 +7376,7 @@ AC_SUBST(c_target_objs)
 AC_SUBST(cxx_target_objs)
 AC_SUBST(fortran_target_objs)
 AC_SUBST(d_target_objs)
+AC_SUBST(rust_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 b0ea39884aa..2ccda74c979 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -53,6 +53,7 @@ through the macros defined in the @file{.h} file.
 * PCH Target::          Validity checking for precompiled headers.
 * C++ ABI::             Controlling C++ ABI changes.
 * D Language and ABI::  Controlling D ABI changes.
+* Rust Language and ABI:: Controlling Rust ABI changes.
 * Named Address Spaces:: Adding support for named address spaces
 * Misc::                Everything else.
 @end menu
@@ -11065,6 +11066,22 @@ if they have external linkage.  If this flag is false, then instantiated
 decls will be emitted as weak symbols.  The default is @code{false}.
 @end deftypevr
 
+@node Rust Language and ABI
+@section Rust ABI parameters
+@cindex parameters, rust abi
+
+@deftypefn {Rust Target Hook} void TARGET_RUST_CPU_INFO (void)
+Declare all environmental CPU info and features relating to the target CPU
+using the function @code{rust_add_target_info}, which takes a string representing
+the feature key and a string representing the feature value.  Configuration pairs
+predefined by this hook apply to all files that are being compiled.
+@end deftypefn
+
+@deftypefn {Rust Target Hook} void TARGET_RUST_OS_INFO (void)
+Similar to @code{TARGET_RUST_CPU_INFO}, but is used for configuration info
+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 f869ddd5e5b..c90c90f97a4 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -53,6 +53,7 @@ through the macros defined in the @file{.h} file.
 * PCH Target::          Validity checking for precompiled headers.
 * C++ ABI::             Controlling C++ ABI changes.
 * D Language and ABI::  Controlling D ABI changes.
+* Rust Language and ABI:: Controlling Rust ABI changes.
 * Named Address Spaces:: Adding support for named address spaces
 * Misc::                Everything else.
 @end menu
@@ -7327,6 +7328,14 @@ floating-point support; they are not included in this mechanism.
 
 @hook TARGET_D_TEMPLATES_ALWAYS_COMDAT
 
+@node Rust Language and ABI
+@section Rust ABI parameters
+@cindex parameters, rust abi
+
+@hook TARGET_RUST_CPU_INFO
+
+@hook TARGET_RUST_OS_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 6bae85d7b8d..4e1338d21b7 100644
--- a/gcc/genhooks.cc
+++ b/gcc/genhooks.cc
@@ -35,6 +35,7 @@ static struct hook_desc hook_array[] = {
 #include "c-family/c-target.def"
 #include "common/common-target.def"
 #include "d/d-target.def"
+#include "rust/rust-target.def"
 #undef DEFHOOK
 };
 
diff --git a/gcc/rust/rust-target-def.h b/gcc/rust/rust-target-def.h
new file mode 100644
index 00000000000..94c3f9f9a23
--- /dev/null
+++ b/gcc/rust/rust-target-def.h
@@ -0,0 +1,20 @@
+/* rust-target-def.h -- Default initializers for Rust target hooks.
+   Copyright (C) 2020-2022 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 "rust/rust-target-hooks-def.h"
+#include "tree.h"
+#include "hooks.h"
diff --git a/gcc/rust/rust-target.def b/gcc/rust/rust-target.def
new file mode 100644
index 00000000000..6d1ccaf8ad1
--- /dev/null
+++ b/gcc/rust/rust-target.def
@@ -0,0 +1,89 @@
+/* rust-target.def -- Target hook definitions for the Rust front end.
+   Copyright (C) 2020-2022 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 "Rust Target Hook"
+
+HOOK_VECTOR (TARGETRUSTM_INITIALIZER, gcc_targetrustm)
+
+#undef HOOK_PREFIX
+#define HOOK_PREFIX "TARGET_"
+
+/* Environmental CPU info and features (e.g. endianness, pointer size) relating to the target CPU.  */
+DEFHOOK
+(rust_cpu_info,
+ "Declare all environmental CPU info and features relating to the target CPU\n\
+using the function @code{rust_add_target_info}, which takes a string representing\n\
+the feature key and a string representing the feature value.  Configuration pairs\n\
+predefined by this hook apply to all files that are being compiled.",
+ void, (void),
+ hook_void_void)
+
+// TODO: remove: format of DEFHOOK is return type, (param types), default value for function that it translates to
+
+/* Environmental OS info relating to the target OS.  */
+DEFHOOK
+(/*d_os_versions*/rust_os_info,
+ "Similar to @code{TARGET_RUST_CPU_INFO}, but is used for configuration info\n\
+relating to the target operating system.",
+ void, (void),
+ hook_void_void)
+
+/* The sizeof CRITICAL_SECTION or pthread_mutex_t.  */
+/*DEFHOOK
+(d_critsec_size,
+ "Returns the size of the data structure used by the target operating system\n\
+for critical sections and monitors.  For example, on Microsoft Windows this\n\
+would return the @code{sizeof(CRITICAL_SECTION)}, while other platforms that\n\
+implement pthreads would return @code{sizeof(pthread_mutex_t)}.",
+ unsigned, (void),
+ hook_uint_void_0)*/
+
+ /* TODO: add more if required. Possible ones include static C runtime, target_env
+  * or vendor (if not covered by OS), and flags from the driver that may or may not
+  * require a target hook (might instead require a different type of hook) like 
+  * test, debug_assertions, and proc_macro. */
+
+ /* TODO: rustc target support by tier:
+  *   Tier 1 (definitely work):
+  *   -  i686-pc-windows-gnu
+  *   -  i686-pc-windows-msvc
+  *   -  i686-unknown-linux-gnu
+  *   -  x86_64-apple-darwin
+  *   -  x86_64-pc-windows-gnu
+  *   -  x86_64-pc-windows-msvc
+  *   -  x86_64-unknown-linux-gnu
+  *   - Basically, 32-bit and 64-bit x86 for windows (MinGW and MSVC), gnu/linux, and osx
+  *   Other tiers have too much crap, but basic breakdown is:
+  *   Tier 2:
+  *   -  archs: ARM64 (aarch64), ARMv7, ARMv6, asm.js, i586 (32-bit x86 without SSE), mips, 
+  *      mips64, powerpc, powerpc64, risc-v, s390x, sparc, webasm, netbsd, redox (does gcc have support?),
+  *      cloudabi (never head of it; i imagine no gcc support)
+  *   -  oses: ios, fuchsia, android, windows (msvc and mingw), gnu/linux, freebsd, netbsd
+  *   Tier 2.5:
+  *   - powerpc SPE linux, various cloudabi stuff, sparc
+  *   Tier 3:
+  *   - more obscure stuff like UWP support, vxworks, openbsd, dragonflybsd, haiku, bitrig, windows xp,
+  *     cuda, hexagon, and combinations of them and earlier stuff */
+
+/* Close the 'struct gcc_targetrustm' definition.  */
+HOOK_VECTOR_END (C90_EMPTY_HACK)
diff --git a/gcc/rust/rust-target.h b/gcc/rust/rust-target.h
new file mode 100644
index 00000000000..743ac518ebb
--- /dev/null
+++ b/gcc/rust/rust-target.h
@@ -0,0 +1,47 @@
+/* rust-target.h -- Data structure definitions for target-specific Rust
+   behavior. Copyright (C) 2020-2022 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_RUST_TARGET_H
+#define GCC_RUST_TARGET_H
+
+#include "target.h"
+#include "tm.h"
+#include "memmodel.h"
+#include "tm_p.h"
+
+// TODO: find out what this stuff actually does
+#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 "rust-target.def"
+
+/* Each target can provide their own.  */
+extern struct gcc_targetrustm targetrustm;
+/* Some kind of structure to store all rust hook macros (like the
+ * TARGET_RUST_CPU_INFO). This is required to store the function pointers for
+ * the target hooks so that the frontend can call them
+ * and it calls the correct target-specific function.  */
+
+/* Used by target to add predefined version idenditiers.  */
+// extern void d_add_builtin_version (const char *);
+/* Used by target to add target-related info.  */
+extern void
+rust_add_target_info (const char *key, const char *value);
+
+#endif
-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
  2022-07-27 13:40 Rust frontend patches v1 herron.philip
  2022-07-27 13:40 ` [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder herron.philip
  2022-07-27 13:40 ` [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 herron.philip
@ 2022-07-27 13:40 ` herron.philip
  2022-07-27 14:13   ` Richard Earnshaw
  2022-07-27 16:45 ` Rust frontend patches v1 David Malcolm
  3 siblings, 1 reply; 20+ messages in thread
From: herron.philip @ 2022-07-27 13:40 UTC (permalink / raw)
  To: gcc-patches; +Cc: Philip Herron, SimplyTheOther

From: Philip Herron <philip.herron@embecosm.com>

This adds the nessecary target hooks for the arm target.

gcc/ChangeLog:

        * config.gcc: add rust_target_objs for arm

gcc/config/arm/ChangeLog:

	* arm-protos.h: define arm_rust_target_cpu_info
        * arm-rust.cc: new file to generate info
	* arm.h: define TARGET_RUST_CPU_INFO
	* bpabi.h: define TARGET_RUST_OS_INFO
	* freebsd.h: likewise
	* linux-eabi.h: likewise
	* linux-elf.h: likewise
	* netbsd-eabi.h: likewise
	* netbsd-elf.h: likewise
	* rtems.h: likewise
	* symbian.h: likewise
	* t-arm: compile arm-rust.cc
	* uclinux-eabi.h: define TARGET_RUST_OS_INFO
	* uclinux-elf.h: likewise
	* vxworks.h: likewise

Co-authored-by: SimplyTheOther <simplytheother@gmail.com>
---
 gcc/config.gcc                |   1 +
 gcc/config/arm/arm-protos.h   |   3 +
 gcc/config/arm/arm-rust.cc    | 304 ++++++++++++++++++++++++++++++++++
 gcc/config/arm/arm.h          |   3 +
 gcc/config/arm/bpabi.h        |  11 ++
 gcc/config/arm/freebsd.h      |   9 +
 gcc/config/arm/linux-eabi.h   |   8 +
 gcc/config/arm/linux-elf.h    |   5 +
 gcc/config/arm/netbsd-eabi.h  |  10 ++
 gcc/config/arm/netbsd-elf.h   |   8 +
 gcc/config/arm/rtems.h        |  14 ++
 gcc/config/arm/symbian.h      |  15 ++
 gcc/config/arm/t-arm          |   4 +
 gcc/config/arm/uclinux-eabi.h |  13 ++
 gcc/config/arm/uclinux-elf.h  |  12 ++
 gcc/config/arm/vxworks.h      |  14 ++
 16 files changed, 434 insertions(+)
 create mode 100644 gcc/config/arm/arm-rust.cc

diff --git a/gcc/config.gcc b/gcc/config.gcc
index cdd4fb4392a..9d686019b28 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -368,6 +368,7 @@ arm*-*-*)
 	c_target_objs="arm-c.o"
 	cxx_target_objs="arm-c.o"
 	d_target_objs="arm-d.o"
+        rust_target_objs="arm-rust.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"
 	;;
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index f8aabbdae37..9513f96fdbc 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -406,6 +406,9 @@ extern void arm_cpu_cpp_builtins (struct cpp_reader *);
 extern void arm_d_target_versions (void);
 extern void arm_d_register_target_info (void);
 
+/* Defined in arm-rust.c  */
+extern void arm_rust_target_cpu_info (void);
+
 extern bool arm_is_constant_pool_ref (rtx);
 
 /* The bits in this mask specify which instruction scheduling options should
diff --git a/gcc/config/arm/arm-rust.cc b/gcc/config/arm/arm-rust.cc
new file mode 100644
index 00000000000..7c83e3fa3a6
--- /dev/null
+++ b/gcc/config/arm/arm-rust.cc
@@ -0,0 +1,304 @@
+/* Subroutines for the Rust front end on the ARM architecture.
+   Copyright (C) 2020 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/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "rust/rust-target.h"
+#include "rust/rust-target-def.h"
+
+/* Implement TARGET_RUST_CPU_INFO for ARM targets.  */
+
+void arm_rust_target_cpu_info(void) {
+    rust_add_target_info("target_arch", "arm");
+
+    /* TODO: further research support for CLREX, acquire-release (lda/ldaex), slow-fp-brcc (slow FP
+     * compare and branch), perfmon, trustzone, fpao, fuse-aes, fuse-literals, read-tp-hard, zcz,
+     * prof-unpr, slow-vgetlni32, slow-vdup32, prefer-vmovsr, prefer-ishst, muxed-units, slow-odd-reg,
+     * slow-load-D-subreg, wide-stride-vfp, dont-widen-vmovs, splat-vfp-neon, expand-fp-mlx,
+     * vmlx-hazards, neon-fpmovs, neonfp (as in using neon for scalar fp), vldn-align,
+     * nonpipelined-vfp, slowfpvmlx, slowfpvfmx, vmlx-forwarding, 32bit (prefer 32-bit Thumb),
+     * loop-align, mve1beat, mve2beat, mve4beat, avoid-partial-cpsr, cheap-predictable-cpsr,
+     * avoid-movs-shop, ret-addr-stack, no-branch-predictor, virtualization, nacl-trap, execute-only,
+     * reserve-r9, no-movt, no-neg-immediates, use-misched, disable-postra-scheduler, lob (Low
+     * Overhead Branch), noarm, cde - can't find them. */
+    /* TODO: figure out if gcc has an equivalent to "fpregs" (floating-point registers even if only
+     * used for integer - shared between VFP and MVE).  */
+    if (TARGET_VFPD32)
+        rust_add_target_info("target_feature", "d32");
+    bool hasFeatureVFP2 = bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv2) && TARGET_VFP_DOUBLE;
+    if (hasFeatureVFP2) {
+        rust_add_target_info("target_feature", "vfp2");
+
+        // also added implied features that aren't separately supported in gcc
+        rust_add_target_info("target_feature", "vfp2sp");
+    }
+    // minimal VFPv3 support - support for instruction set, not necessarily full
+    bool minVFP3 = TARGET_VFP3 && bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv2);
+    if (minVFP3) {
+        rust_add_target_info("target_feature", "vfp3d16sp");
+
+        if (TARGET_VFPD32)
+            rust_add_target_info("target_feature", "vfp3sp");
+
+        if (TARGET_VFP_DOUBLE) {
+            rust_add_target_info("target_feature", "vfp3d16");
+
+            if (TARGET_VFPD32) {
+                rust_add_target_info("target_feature", "vfp3");
+
+                if (bitmap_bit_p(arm_active_target.isa, isa_bit_neon))
+                    rust_add_target_info("target_feature", "neon");
+            }
+        }
+    }
+    bool hasFeatureVFP3 = minVFP3 && TARGET_VFP_DOUBLE && TARGET_VFPD32;
+    bool hasFeatureFP16 = bitmap_bit_p(arm_active_target.isa, isa_bit_fp16conv);
+    if (hasFeatureFP16)
+        rust_add_target_info("target_info", "fp16");
+    bool minVFP4 = minVFP3 && bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv4) && hasFeatureFP16;
+    if (minVFP4) {
+        rust_add_target_info("target_feature", "vfp4d16sp");
+
+        if (TARGET_VFPD32)
+            rust_add_target_info("target_feature", "vfp4sp");
+
+        if (TARGET_VFP_DOUBLE) {
+            rust_add_target_info("target_feature", "vfp4d16");
+
+            if (TARGET_VFPD32) {
+                rust_add_target_info("target_feature", "vfp4");
+            }
+        }
+    }
+    // NOTE: supposedly "fp-armv8" features in llvm are the same as "fpv5", so creating them based on
+    // that
+    bool minFP_ARMv8 = minVFP4 && TARGET_VFP5;
+    if (minFP_ARMv8) {
+        rust_add_target_info("target_feature", "fp-armv8d16sp");
+
+        if (TARGET_VFPD32)
+            rust_add_target_info("target_feature", "fp-armv8sp");
+
+        if (TARGET_VFP_DOUBLE) {
+            rust_add_target_info("target_feature", "fp-armv8d16");
+
+            if (TARGET_VFPD32) {
+                rust_add_target_info("target_feature", "fp-armv8");
+            }
+        }
+
+        if (bitmap_bit_p(arm_active_target.isa, isa_bit_fp16)) {
+            rust_add_target_info("target_feature", "fullfp16");
+
+            if (bitmap_bit_p(arm_active_target.isa, isa_bit_fp16fml))
+                rust_add_target_info("target_feature", "fp16fml");
+        }
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_tdiv))
+        rust_add_target_info("target_feature", "hwdiv");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_adiv))
+        rust_add_target_info("target_feature", "hwdiv-arm");
+    // TODO: I'm not sure if there's an exact correlation here (data barrier), so maybe research
+    // There's also the question of whether this also means "full data barrier" ("fdb" in llvm)
+    if (TARGET_HAVE_MEMORY_BARRIER)
+        rust_add_target_info("target_feature", "db");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cmse))
+        rust_add_target_info("target_feature", "8msecext");
+    /* TODO: note that sha2 is an option for aarch64 in gcc but not for arm, so no feature here
+     * possible. The same goes for aes. However, as llvm has them as prerequisites for crypto, they
+     * are enabled with it. */
+    if (TARGET_CRYPTO) {
+        rust_add_target_info("target_feature", "crypto");
+        rust_add_target_info("target_feature", "sha2");
+        rust_add_target_info("target_feature", "aes");
+    }
+    if (TARGET_CRC32)
+        rust_add_target_info("target_feature", "crc");
+    if (TARGET_DOTPROD)
+        rust_add_target_info("target_feature", "dotprod");
+    // TODO: supposedly gcc supports RAS, but I couldn't find the option, so leaving out "ras" for now
+    if (TARGET_DSP_MULTIPLY)
+        rust_add_target_info("target_feature", "dsp");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_mp))
+        rust_add_target_info("target_feature", "mp");
+    // TODO: figure out the exact strict-align feature, which I'm pretty sure GCC has
+    // TODO: figure out how to access long call data (which is in GCC) for "long-calls"
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_sb))
+        rust_add_target_info("target_feature", "sb");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_bf16))
+        rust_add_target_info("target_feature", "bf16");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_i8mm))
+        rust_add_target_info("target_feature", "i8mm");
+    switch (TARGET_ARM_ARCH_PROFILE) {
+        case 'A':
+            rust_add_target_info("target_feature", "aclass");
+            break;
+        case 'R':
+            rust_add_target_info("target_feature", "rclass");
+            break;
+        case 'M':
+            rust_add_target_info("target_feature", "mclass");
+            break;
+        default:
+            fprintf(stderr, "Screwed up profile selection in arm-rust.c - unknown profile '%c'",
+              TARGET_ARM_ARCH_PROFILE);
+            break;
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_thumb2))
+        rust_add_target_info("target_feature", "thumb2");
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv4)
+        && bitmap_bit_p(arm_active_target.isa, isa_bit_notm)
+        && bitmap_bit_p(arm_active_target.isa, isa_bit_thumb)) {
+        rust_add_target_info("target_feature", "v4t");
+
+        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv5t)) {
+            rust_add_target_info("target_feature", "v5t");
+
+            if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv5te)) {
+                rust_add_target_info("target_feature", "v5te");
+
+                if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv6)
+                    && bitmap_bit_p(arm_active_target.isa, isa_bit_be8)) {
+                    rust_add_target_info("target_feature", "v6");
+
+                    // note: this definition of "ARMv6m" listed as "suspect" in arm-cpus.in
+                    rust_add_target_info("target_feature", "v6m");
+
+                    bool hasV8BaselineOps = bitmap_bit_p(arm_active_target.isa, isa_bit_armv8)
+                                            && bitmap_bit_p(arm_active_target.isa, isa_bit_cmse)
+                                            && bitmap_bit_p(arm_active_target.isa, isa_bit_tdiv);
+                    if (hasV8BaselineOps)
+                        rust_add_target_info("target_feature", "v8m");
+
+                    bool hasV6kOps = bitmap_bit_p(arm_active_target.isa, isa_bit_armv6k);
+                    if (hasV6kOps) {
+                        rust_add_target_info("target_feature", "v6k");
+                    }
+
+                    if (bitmap_bit_p(arm_active_target.isa, isa_bit_thumb2) && hasV8BaselineOps
+                        && hasV6kOps) {
+                        rust_add_target_info("target_feature", "v6t2");
+
+                        // note that arm-cpus.in refers to this (ARMv7) as suspect
+                        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv7)) {
+                            rust_add_target_info("target_feature", "v7");
+
+                            rust_add_target_info("target_feature", "v8m.main");
+
+                            if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_1m_main))
+                                rust_add_target_info("target_feature", "v8.1m.main");
+
+                            // dummy: can't find feature acquire-release, so dummy true variable
+                            bool hasAcquireRelease = true;
+                            if (hasAcquireRelease && bitmap_bit_p(arm_active_target.isa, isa_bit_adiv)
+                                && bitmap_bit_p(arm_active_target.isa, isa_bit_lpae)
+                                && bitmap_bit_p(arm_active_target.isa, isa_bit_mp)
+                                && bitmap_bit_p(arm_active_target.isa, isa_bit_sec)) {
+                                rust_add_target_info("target_feature", "v8");
+
+                                if (TARGET_CRC32
+                                    && bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_1)) {
+                                    rust_add_target_info("target_feature", "v8.1a");
+
+                                    if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_2)) {
+                                        rust_add_target_info("target_feature", "v8.2a");
+
+                                        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_3)) {
+                                            rust_add_target_info("target_feature", "v8.3a");
+
+                                            if (bitmap_bit_p(
+                                                  arm_active_target.isa, isa_bit_armv8_4)) {
+                                                rust_add_target_info("target_feature", "v8.4a");
+                                                // note: llvm, but not gcc, also wants dotprod for
+                                                // v8.4
+
+                                                if (bitmap_bit_p(arm_active_target.isa, isa_bit_sb)
+                                                    && bitmap_bit_p(
+                                                      arm_active_target.isa, isa_bit_predres)
+                                                    && bitmap_bit_p(
+                                                      arm_active_target.isa, isa_bit_armv8_5)) {
+                                                    rust_add_target_info("target_feature", "v8.5a");
+
+                                                    if (bitmap_bit_p(
+                                                          arm_active_target.isa, isa_bit_armv8_6))
+                                                        rust_add_target_info(
+                                                          "target_feature", "v8.6a");
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_mve)
+        && bitmap_bit_p(arm_active_target.isa, isa_bit_vfp_base)
+        && bitmap_bit_p(arm_active_target.isa, isa_bit_armv7em)) {
+        rust_add_target_info("target_feature", "mve");
+
+        if (minFP_ARMv8 && bitmap_bit_p(arm_active_target.isa, isa_bit_fp16)
+            && bitmap_bit_p(arm_active_target.isa, isa_bit_mve_float))
+            rust_add_target_info("target_feature", "mve.fp");
+    }
+    // Note: no direct option for "cde" found, but it is implicitly activated via cdecpx, so do it
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp0)) {
+        rust_add_target_info("target_feature", "cdecp0");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp1)) {
+        rust_add_target_info("target_feature", "cdecp1");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp2)) {
+        rust_add_target_info("target_feature", "cdecp2");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp3)) {
+        rust_add_target_info("target_feature", "cdecp3");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp4)) {
+        rust_add_target_info("target_feature", "cdecp4");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp5)) {
+        rust_add_target_info("target_feature", "cdecp5");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp6)) {
+        rust_add_target_info("target_feature", "cdecp6");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp7)) {
+        rust_add_target_info("target_feature", "cdecp7");
+        rust_add_target_info("target_feature", "cde");
+    }
+    if (TARGET_SOFT_FLOAT)
+        rust_add_target_info("target_feature", "soft-float");
+    // should be correct option (i.e. thumb mode rather than just thumb-aware) as TARGET_ARM is
+    // inverse
+    if (TARGET_THUMB)
+        rust_add_target_info("target_feature", "thumb-mode");
+    // TODO: consider doing the processors as target features, but honestly they don't seem to fit
+}
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index f479540812a..abaec9e71e6 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -51,6 +51,9 @@ extern char arm_arch_name[];
 #define TARGET_D_CPU_VERSIONS arm_d_target_versions
 #define TARGET_D_REGISTER_CPU_TARGET_INFO arm_d_register_target_info
 
+/* Target CPU info for Rust.  */
+#define TARGET_RUST_CPU_INFO arm_rust_target_cpu_info
+
 #include "config/arm/arm-opts.h"
 
 /* The processor for which instructions should be scheduled.  */
diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
index 70984ddd147..0df5dd0f31a 100644
--- a/gcc/config/arm/bpabi.h
+++ b/gcc/config/arm/bpabi.h
@@ -104,6 +104,17 @@
 #define TARGET_OS_CPP_BUILTINS() \
   TARGET_BPABI_CPP_BUILTINS()
 
+#define BPABI_TARGET_RUST_OS_INFO() \
+  do { \
+    /*TODO: is this even an OS? What should go here?*/ \
+  } while (0)
+
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in bpabi.h - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO() \
+  BPABI_TARGET_RUST_OS_INFO()
+
 /* The BPABI specifies the use of .{init,fini}_array.  Therefore, we
    do not want GCC to put anything into the .{init,fini} sections.  */
 #undef INIT_SECTION_ASM_OP
diff --git a/gcc/config/arm/freebsd.h b/gcc/config/arm/freebsd.h
index 2bd0dc97df3..d662ab005d6 100644
--- a/gcc/config/arm/freebsd.h
+++ b/gcc/config/arm/freebsd.h
@@ -83,6 +83,15 @@
     }						\
   while (false)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in freebsd.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO() 		\
+  do {						\
+    FBSD_TARGET_RUST_OS_INFO ();		\
+    BPABI_TARGET_RUST_OS_INFO ();		\
+  } while (0)
+
 /* We default to a soft-float ABI so that binaries can run on all
    target hardware.  */
 #undef TARGET_DEFAULT_FLOAT_ABI
diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
index 50cc0bc6d08..a255ac0f1a7 100644
--- a/gcc/config/arm/linux-eabi.h
+++ b/gcc/config/arm/linux-eabi.h
@@ -33,6 +33,14 @@
 #define EXTRA_TARGET_D_OS_VERSIONS()		\
   ANDROID_TARGET_D_OS_VERSIONS();
 
+#define EXTRA_TARGET_RUST_OS_INFO()		\
+  do { 						\
+    BPABI_TARGET_RUST_OS_INFO();		\
+    GNU_USER_TARGET_RUST_OS_INFO();		\
+    ANDROID_TARGET_RUST_OS_INFO();		\
+    /*TODO: ensure that this makes target_os 'linux' properly and stuff*/ \
+  while (0)
+
 /* We default to a soft-float ABI so that binaries can run on all
    target hardware.  If you override this to use the hard-float ABI then
    change the setting of GLIBC_DYNAMIC_LINKER_DEFAULT as well.  */
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index df3da67c4f0..0859945ed05 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -83,6 +83,11 @@
     }						\
   while (0)
 
+#define TARGET_RUST_OS_INFO()		\
+   do {						\
+	   GNU_USER_TARGET_RUST_OS_INFO();	\
+   } while (0)
+
 /* Call the function profiler with a given profile label.  */
 #undef  ARM_FUNCTION_PROFILER
 #define ARM_FUNCTION_PROFILER(STREAM, LABELNO)  			\
diff --git a/gcc/config/arm/netbsd-eabi.h b/gcc/config/arm/netbsd-eabi.h
index c85fcd3e385..a47b2ca3776 100644
--- a/gcc/config/arm/netbsd-eabi.h
+++ b/gcc/config/arm/netbsd-eabi.h
@@ -64,6 +64,16 @@
     }						\
   while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in netbsd-eabi.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {						\
+  	if (TARGET_AAPCS_BASED)			\
+      BPABI_TARGET_RUST_OS_INFO();		\
+    NETBSD_TARGET_RUST_OS_INFO();		\
+  } while (0)
+
 #undef SUBTARGET_CPP_SPEC
 #define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
 
diff --git a/gcc/config/arm/netbsd-elf.h b/gcc/config/arm/netbsd-elf.h
index d239c734c5c..e74cdcc6503 100644
--- a/gcc/config/arm/netbsd-elf.h
+++ b/gcc/config/arm/netbsd-elf.h
@@ -51,6 +51,14 @@
     }					\
   while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in netbsd-elf.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()	\
+  do {					\
+    NETBSD_TARGET_RUST_OS_INFO();	\
+  } while (0)
+
 #undef SUBTARGET_CPP_SPEC
 #define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
 
diff --git a/gcc/config/arm/rtems.h b/gcc/config/arm/rtems.h
index a569343451a..56f978bf73e 100644
--- a/gcc/config/arm/rtems.h
+++ b/gcc/config/arm/rtems.h
@@ -33,4 +33,18 @@
 	TARGET_BPABI_CPP_BUILTINS();    	\
     } while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in rtems.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {					\
+    /*note: as far as I know, rustc has no supported for rtems, so this is just guessed*/ \
+    /*everything is subject to change, especially target_env and target_family - TODO*/ \
+    builtin_rust_info ("target_family", "unix");	\
+    builtin_rust_info ("target_os", "rtems");	\
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "");	\
+    BPABI_TARGET_RUST_OS_INFO();	\
+  } while (0)
+
 #define ARM_DEFAULT_SHORT_ENUMS false
diff --git a/gcc/config/arm/symbian.h b/gcc/config/arm/symbian.h
index 7df39170180..81c7cc00a27 100644
--- a/gcc/config/arm/symbian.h
+++ b/gcc/config/arm/symbian.h
@@ -78,6 +78,21 @@
     }								\
   while (false)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in symbian.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {					\
+    /*note: as far as I know, rustc has no supported for symbian, so this is just guessed*/ \
+    /*everything is subject to change, especially target_env and target_vendor - TODO*/ \
+    /*some triple examples i've seen are "arm-nokia-symbian-eabi" and possibly "arm-none-symbian-elf"*/ \
+    builtin_rust_info ("target_family", "");	\
+    builtin_rust_info ("target_os", "symbian");	\
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "");	\
+    BPABI_TARGET_RUST_OS_INFO();	\
+  } while (0)
+
 /* On SymbianOS, these sections are not writable, so we use "a",
    rather than "aw", for the section attributes.  */
 #undef ARM_EABI_CTORS_SECTION_OP
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 041cc6ec045..d093f3c789c 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -172,6 +172,10 @@ arm-d.o: $(srcdir)/config/arm/arm-d.cc
 	$(COMPILE) $<
 	$(POSTCOMPILE)
 
+arm-rust.o: $(srcdir)/config/arm/arm-rust.cc
+	$(COMPILE) $<
+	$(POSTCOMPILE)
+
 arm-common.o: arm-cpu-cdata.h
 
 driver-arm.o: arm-native.h
diff --git a/gcc/config/arm/uclinux-eabi.h b/gcc/config/arm/uclinux-eabi.h
index 362d2b5ebd8..54bf78cdc0d 100644
--- a/gcc/config/arm/uclinux-eabi.h
+++ b/gcc/config/arm/uclinux-eabi.h
@@ -46,6 +46,19 @@
     }						\
   while (false)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in uclinux-eabi.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {					\
+    BPABI_TARGET_RUST_OS_INFO();	\
+    /*note: as far as I know, rustc does not distinguish between uclinux and regular linux kernels*/ \
+    builtin_rust_info ("target_family", "unix");	   \
+    builtin_rust_info ("target_os", "linux");	      \
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "gnu");	         \
+  } while (0)
+
 #undef SUBTARGET_EXTRA_LINK_SPEC
 #define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi -elf2flt" \
   " --pic-veneer --target2=abs"
diff --git a/gcc/config/arm/uclinux-elf.h b/gcc/config/arm/uclinux-elf.h
index 921440d49bd..3fcaf2d6acb 100644
--- a/gcc/config/arm/uclinux-elf.h
+++ b/gcc/config/arm/uclinux-elf.h
@@ -48,6 +48,18 @@
     }						\
   while (false)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in uclinux-elf.h (arm) - c++ undefines it and redefines it."
+#endif
+#define TARGET_RUST_OS_INFO()		\
+  do {					\
+    /*note: as far as I know, rustc does not distinguish between uclinux and regular linux kernels*/ \
+    builtin_rust_info ("target_family", "unix");	   \
+    builtin_rust_info ("target_os", "linux");	      \
+    builtin_rust_info ("target_vendor", "unknown");	\
+    builtin_rust_info ("target_env", "gnu");	         \
+  } while (0)
+
 /* The GNU C++ standard library requires that these macros be defined.  */
 #undef CPLUSPLUS_CPP_SPEC
 #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h
index 2bcd01edc97..0d4989cb52a 100644
--- a/gcc/config/arm/vxworks.h
+++ b/gcc/config/arm/vxworks.h
@@ -75,6 +75,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     MAYBE_TARGET_BPABI_CPP_BUILTINS ();			\
   } while (0)
 
+#ifdef TARGET_RUST_OS_INFO
+# error "TARGET_RUST_OS_INFO already defined in vxworks.h (arm) - c++ undefines it and redefines it."
+#endif
+#ifdef BPABI_TARGET_RUST_OS_INFO
+# define MAYBE_BPABI_TARGET_RUST_OS_INFO BPABI_TARGET_RUST_OS_INFO
+#else
+# define MAYBE_BPABI_TARGET_RUST_OS_INFO()
+#endif
+#define TARGET_RUST_OS_INFO()			\
+  do {			\
+    VXWORKS_TARGET_RUST_OS_INFO ();			\
+    MAYBE_BPABI_TARGET_RUST_OS_INFO ();			\
+  } while (0)
+
 #undef SUBTARGET_OVERRIDE_OPTIONS
 #define SUBTARGET_OVERRIDE_OPTIONS VXWORKS_OVERRIDE_OPTIONS
 
-- 
2.25.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
  2022-07-27 13:40 ` [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM herron.philip
@ 2022-07-27 14:13   ` Richard Earnshaw
  0 siblings, 0 replies; 20+ messages in thread
From: Richard Earnshaw @ 2022-07-27 14:13 UTC (permalink / raw)
  To: philip.herron, gcc-patches; +Cc: herron.philip, SimplyTheOther



On 27/07/2022 14:40, herron.philip--- via Gcc-patches wrote:
> From: Philip Herron <philip.herron@embecosm.com>
> 
> This adds the nessecary target hooks for the arm target.
> 
> gcc/ChangeLog:
> 
>          * config.gcc: add rust_target_objs for arm
> 
> gcc/config/arm/ChangeLog:
> 
> 	* arm-protos.h: define arm_rust_target_cpu_info
>          * arm-rust.cc: new file to generate info
> 	* arm.h: define TARGET_RUST_CPU_INFO
> 	* bpabi.h: define TARGET_RUST_OS_INFO
> 	* freebsd.h: likewise
> 	* linux-eabi.h: likewise
> 	* linux-elf.h: likewise
> 	* netbsd-eabi.h: likewise
> 	* netbsd-elf.h: likewise
> 	* rtems.h: likewise
> 	* symbian.h: likewise
> 	* t-arm: compile arm-rust.cc
> 	* uclinux-eabi.h: define TARGET_RUST_OS_INFO
> 	* uclinux-elf.h: likewise
> 	* vxworks.h: likewise
> 
> Co-authored-by: SimplyTheOther <simplytheother@gmail.com>
> ---
>   gcc/config.gcc                |   1 +
>   gcc/config/arm/arm-protos.h   |   3 +
>   gcc/config/arm/arm-rust.cc    | 304 ++++++++++++++++++++++++++++++++++
>   gcc/config/arm/arm.h          |   3 +
>   gcc/config/arm/bpabi.h        |  11 ++
>   gcc/config/arm/freebsd.h      |   9 +
>   gcc/config/arm/linux-eabi.h   |   8 +
>   gcc/config/arm/linux-elf.h    |   5 +
>   gcc/config/arm/netbsd-eabi.h  |  10 ++
>   gcc/config/arm/netbsd-elf.h   |   8 +
>   gcc/config/arm/rtems.h        |  14 ++
>   gcc/config/arm/symbian.h      |  15 ++
>   gcc/config/arm/t-arm          |   4 +
>   gcc/config/arm/uclinux-eabi.h |  13 ++
>   gcc/config/arm/uclinux-elf.h  |  12 ++
>   gcc/config/arm/vxworks.h      |  14 ++
>   16 files changed, 434 insertions(+)
>   create mode 100644 gcc/config/arm/arm-rust.cc
> 
> diff --git a/gcc/config.gcc b/gcc/config.gcc
> index cdd4fb4392a..9d686019b28 100644
> --- a/gcc/config.gcc
> +++ b/gcc/config.gcc
> @@ -368,6 +368,7 @@ arm*-*-*)
>   	c_target_objs="arm-c.o"
>   	cxx_target_objs="arm-c.o"
>   	d_target_objs="arm-d.o"
> +        rust_target_objs="arm-rust.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"
>   	;;
> diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
> index f8aabbdae37..9513f96fdbc 100644
> --- a/gcc/config/arm/arm-protos.h
> +++ b/gcc/config/arm/arm-protos.h
> @@ -406,6 +406,9 @@ extern void arm_cpu_cpp_builtins (struct cpp_reader *);
>   extern void arm_d_target_versions (void);
>   extern void arm_d_register_target_info (void);
>   
> +/* Defined in arm-rust.c  */
> +extern void arm_rust_target_cpu_info (void);
> +
>   extern bool arm_is_constant_pool_ref (rtx);
>   
>   /* The bits in this mask specify which instruction scheduling options should
> diff --git a/gcc/config/arm/arm-rust.cc b/gcc/config/arm/arm-rust.cc
> new file mode 100644
> index 00000000000..7c83e3fa3a6
> --- /dev/null
> +++ b/gcc/config/arm/arm-rust.cc
> @@ -0,0 +1,304 @@
> +/* Subroutines for the Rust front end on the ARM architecture.
> +   Copyright (C) 2020 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/>.  */
> +
> +#include "config.h"
> +#include "system.h"
> +#include "coretypes.h"
> +#include "tm.h"
> +#include "tm_p.h"
> +#include "rust/rust-target.h"
> +#include "rust/rust-target-def.h"
> +
> +/* Implement TARGET_RUST_CPU_INFO for ARM targets.  */
> +
> +void arm_rust_target_cpu_info(void) {
> +    rust_add_target_info("target_arch", "arm");
> +
> +    /* TODO: further research support for CLREX, acquire-release (lda/ldaex), slow-fp-brcc (slow FP
> +     * compare and branch), perfmon, trustzone, fpao, fuse-aes, fuse-literals, read-tp-hard, zcz,
> +     * prof-unpr, slow-vgetlni32, slow-vdup32, prefer-vmovsr, prefer-ishst, muxed-units, slow-odd-reg,
> +     * slow-load-D-subreg, wide-stride-vfp, dont-widen-vmovs, splat-vfp-neon, expand-fp-mlx,
> +     * vmlx-hazards, neon-fpmovs, neonfp (as in using neon for scalar fp), vldn-align,
> +     * nonpipelined-vfp, slowfpvmlx, slowfpvfmx, vmlx-forwarding, 32bit (prefer 32-bit Thumb),
> +     * loop-align, mve1beat, mve2beat, mve4beat, avoid-partial-cpsr, cheap-predictable-cpsr,
> +     * avoid-movs-shop, ret-addr-stack, no-branch-predictor, virtualization, nacl-trap, execute-only,
> +     * reserve-r9, no-movt, no-neg-immediates, use-misched, disable-postra-scheduler, lob (Low
> +     * Overhead Branch), noarm, cde - can't find them. */
> +    /* TODO: figure out if gcc has an equivalent to "fpregs" (floating-point registers even if only
> +     * used for integer - shared between VFP and MVE).  */

This doesn't look to be the right approach to me.  These feature bits 
are very definitely /internal/ to the compiler and should not be exposed 
directly to users.  There's no guarantee of stability and no direct 
guarantee that they map onto something usable in a target processor.

If you want something that's going to be reasonably stable, look at the 
architecture extension options, noting that some options are context 
dependent (so, for example, +fp means different things depending on the 
base architecture its applied to).

Your other option would be to look at the official architecture feature 
names (as defined in the various Arm ARM documents, but the GCC options 
try to follow those names quite closely for more modern revisions of the 
architecture.

Finally, this code will need to be reformatted in GNU style at some point.

> +    if (TARGET_VFPD32)
> +        rust_add_target_info("target_feature", "d32");
> +    bool hasFeatureVFP2 = bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv2) && TARGET_VFP_DOUBLE;
> +    if (hasFeatureVFP2) {
> +        rust_add_target_info("target_feature", "vfp2");
> +
> +        // also added implied features that aren't separately supported in gcc
> +        rust_add_target_info("target_feature", "vfp2sp");
> +    }
> +    // minimal VFPv3 support - support for instruction set, not necessarily full
> +    bool minVFP3 = TARGET_VFP3 && bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv2);
> +    if (minVFP3) {
> +        rust_add_target_info("target_feature", "vfp3d16sp");
> +
> +        if (TARGET_VFPD32)
> +            rust_add_target_info("target_feature", "vfp3sp");
> +
> +        if (TARGET_VFP_DOUBLE) {
> +            rust_add_target_info("target_feature", "vfp3d16");
> +
> +            if (TARGET_VFPD32) {
> +                rust_add_target_info("target_feature", "vfp3");
> +
> +                if (bitmap_bit_p(arm_active_target.isa, isa_bit_neon))
> +                    rust_add_target_info("target_feature", "neon");
> +            }
> +        }
> +    }
> +    bool hasFeatureVFP3 = minVFP3 && TARGET_VFP_DOUBLE && TARGET_VFPD32;
> +    bool hasFeatureFP16 = bitmap_bit_p(arm_active_target.isa, isa_bit_fp16conv);
> +    if (hasFeatureFP16)
> +        rust_add_target_info("target_info", "fp16");
> +    bool minVFP4 = minVFP3 && bitmap_bit_p(arm_active_target.isa, isa_bit_vfpv4) && hasFeatureFP16;
> +    if (minVFP4) {
> +        rust_add_target_info("target_feature", "vfp4d16sp");
> +
> +        if (TARGET_VFPD32)
> +            rust_add_target_info("target_feature", "vfp4sp");
> +
> +        if (TARGET_VFP_DOUBLE) {
> +            rust_add_target_info("target_feature", "vfp4d16");
> +
> +            if (TARGET_VFPD32) {
> +                rust_add_target_info("target_feature", "vfp4");
> +            }
> +        }
> +    }
> +    // NOTE: supposedly "fp-armv8" features in llvm are the same as "fpv5", so creating them based on
> +    // that
> +    bool minFP_ARMv8 = minVFP4 && TARGET_VFP5;
> +    if (minFP_ARMv8) {
> +        rust_add_target_info("target_feature", "fp-armv8d16sp");
> +
> +        if (TARGET_VFPD32)
> +            rust_add_target_info("target_feature", "fp-armv8sp");
> +
> +        if (TARGET_VFP_DOUBLE) {
> +            rust_add_target_info("target_feature", "fp-armv8d16");
> +
> +            if (TARGET_VFPD32) {
> +                rust_add_target_info("target_feature", "fp-armv8");
> +            }
> +        }
> +
> +        if (bitmap_bit_p(arm_active_target.isa, isa_bit_fp16)) {
> +            rust_add_target_info("target_feature", "fullfp16");
> +
> +            if (bitmap_bit_p(arm_active_target.isa, isa_bit_fp16fml))
> +                rust_add_target_info("target_feature", "fp16fml");
> +        }
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_tdiv))
> +        rust_add_target_info("target_feature", "hwdiv");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_adiv))
> +        rust_add_target_info("target_feature", "hwdiv-arm");
> +    // TODO: I'm not sure if there's an exact correlation here (data barrier), so maybe research
> +    // There's also the question of whether this also means "full data barrier" ("fdb" in llvm)
> +    if (TARGET_HAVE_MEMORY_BARRIER)
> +        rust_add_target_info("target_feature", "db");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cmse))
> +        rust_add_target_info("target_feature", "8msecext");
> +    /* TODO: note that sha2 is an option for aarch64 in gcc but not for arm, so no feature here
> +     * possible. The same goes for aes. However, as llvm has them as prerequisites for crypto, they
> +     * are enabled with it. */
> +    if (TARGET_CRYPTO) {
> +        rust_add_target_info("target_feature", "crypto");
> +        rust_add_target_info("target_feature", "sha2");
> +        rust_add_target_info("target_feature", "aes");
> +    }
> +    if (TARGET_CRC32)
> +        rust_add_target_info("target_feature", "crc");
> +    if (TARGET_DOTPROD)
> +        rust_add_target_info("target_feature", "dotprod");
> +    // TODO: supposedly gcc supports RAS, but I couldn't find the option, so leaving out "ras" for now
> +    if (TARGET_DSP_MULTIPLY)
> +        rust_add_target_info("target_feature", "dsp");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_mp))
> +        rust_add_target_info("target_feature", "mp");
> +    // TODO: figure out the exact strict-align feature, which I'm pretty sure GCC has
> +    // TODO: figure out how to access long call data (which is in GCC) for "long-calls"
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_sb))
> +        rust_add_target_info("target_feature", "sb");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_bf16))
> +        rust_add_target_info("target_feature", "bf16");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_i8mm))
> +        rust_add_target_info("target_feature", "i8mm");
> +    switch (TARGET_ARM_ARCH_PROFILE) {
> +        case 'A':
> +            rust_add_target_info("target_feature", "aclass");
> +            break;
> +        case 'R':
> +            rust_add_target_info("target_feature", "rclass");
> +            break;
> +        case 'M':
> +            rust_add_target_info("target_feature", "mclass");
> +            break;
> +        default:
> +            fprintf(stderr, "Screwed up profile selection in arm-rust.c - unknown profile '%c'",
> +              TARGET_ARM_ARCH_PROFILE);
> +            break;
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_thumb2))
> +        rust_add_target_info("target_feature", "thumb2");
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv4)
> +        && bitmap_bit_p(arm_active_target.isa, isa_bit_notm)
> +        && bitmap_bit_p(arm_active_target.isa, isa_bit_thumb)) {
> +        rust_add_target_info("target_feature", "v4t");
> +
> +        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv5t)) {
> +            rust_add_target_info("target_feature", "v5t");
> +
> +            if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv5te)) {
> +                rust_add_target_info("target_feature", "v5te");
> +
> +                if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv6)
> +                    && bitmap_bit_p(arm_active_target.isa, isa_bit_be8)) {
> +                    rust_add_target_info("target_feature", "v6");
> +
> +                    // note: this definition of "ARMv6m" listed as "suspect" in arm-cpus.in
> +                    rust_add_target_info("target_feature", "v6m");
> +
> +                    bool hasV8BaselineOps = bitmap_bit_p(arm_active_target.isa, isa_bit_armv8)
> +                                            && bitmap_bit_p(arm_active_target.isa, isa_bit_cmse)
> +                                            && bitmap_bit_p(arm_active_target.isa, isa_bit_tdiv);
> +                    if (hasV8BaselineOps)
> +                        rust_add_target_info("target_feature", "v8m");
> +
> +                    bool hasV6kOps = bitmap_bit_p(arm_active_target.isa, isa_bit_armv6k);
> +                    if (hasV6kOps) {
> +                        rust_add_target_info("target_feature", "v6k");
> +                    }
> +
> +                    if (bitmap_bit_p(arm_active_target.isa, isa_bit_thumb2) && hasV8BaselineOps
> +                        && hasV6kOps) {
> +                        rust_add_target_info("target_feature", "v6t2");
> +
> +                        // note that arm-cpus.in refers to this (ARMv7) as suspect
> +                        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv7)) {
> +                            rust_add_target_info("target_feature", "v7");
> +
> +                            rust_add_target_info("target_feature", "v8m.main");
> +
> +                            if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_1m_main))
> +                                rust_add_target_info("target_feature", "v8.1m.main");
> +
> +                            // dummy: can't find feature acquire-release, so dummy true variable
> +                            bool hasAcquireRelease = true;
> +                            if (hasAcquireRelease && bitmap_bit_p(arm_active_target.isa, isa_bit_adiv)
> +                                && bitmap_bit_p(arm_active_target.isa, isa_bit_lpae)
> +                                && bitmap_bit_p(arm_active_target.isa, isa_bit_mp)
> +                                && bitmap_bit_p(arm_active_target.isa, isa_bit_sec)) {
> +                                rust_add_target_info("target_feature", "v8");
> +
> +                                if (TARGET_CRC32
> +                                    && bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_1)) {
> +                                    rust_add_target_info("target_feature", "v8.1a");
> +
> +                                    if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_2)) {
> +                                        rust_add_target_info("target_feature", "v8.2a");
> +
> +                                        if (bitmap_bit_p(arm_active_target.isa, isa_bit_armv8_3)) {
> +                                            rust_add_target_info("target_feature", "v8.3a");
> +
> +                                            if (bitmap_bit_p(
> +                                                  arm_active_target.isa, isa_bit_armv8_4)) {
> +                                                rust_add_target_info("target_feature", "v8.4a");
> +                                                // note: llvm, but not gcc, also wants dotprod for
> +                                                // v8.4
> +
> +                                                if (bitmap_bit_p(arm_active_target.isa, isa_bit_sb)
> +                                                    && bitmap_bit_p(
> +                                                      arm_active_target.isa, isa_bit_predres)
> +                                                    && bitmap_bit_p(
> +                                                      arm_active_target.isa, isa_bit_armv8_5)) {
> +                                                    rust_add_target_info("target_feature", "v8.5a");
> +
> +                                                    if (bitmap_bit_p(
> +                                                          arm_active_target.isa, isa_bit_armv8_6))
> +                                                        rust_add_target_info(
> +                                                          "target_feature", "v8.6a");
> +                                                }
> +                                            }
> +                                        }
> +                                    }
> +                                }
> +                            }
> +                        }
> +                    }
> +                }
> +            }
> +        }
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_mve)
> +        && bitmap_bit_p(arm_active_target.isa, isa_bit_vfp_base)
> +        && bitmap_bit_p(arm_active_target.isa, isa_bit_armv7em)) {
> +        rust_add_target_info("target_feature", "mve");
> +
> +        if (minFP_ARMv8 && bitmap_bit_p(arm_active_target.isa, isa_bit_fp16)
> +            && bitmap_bit_p(arm_active_target.isa, isa_bit_mve_float))
> +            rust_add_target_info("target_feature", "mve.fp");
> +    }
> +    // Note: no direct option for "cde" found, but it is implicitly activated via cdecpx, so do it
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp0)) {
> +        rust_add_target_info("target_feature", "cdecp0");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp1)) {
> +        rust_add_target_info("target_feature", "cdecp1");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp2)) {
> +        rust_add_target_info("target_feature", "cdecp2");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp3)) {
> +        rust_add_target_info("target_feature", "cdecp3");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp4)) {
> +        rust_add_target_info("target_feature", "cdecp4");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp5)) {
> +        rust_add_target_info("target_feature", "cdecp5");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp6)) {
> +        rust_add_target_info("target_feature", "cdecp6");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (bitmap_bit_p(arm_active_target.isa, isa_bit_cdecp7)) {
> +        rust_add_target_info("target_feature", "cdecp7");
> +        rust_add_target_info("target_feature", "cde");
> +    }
> +    if (TARGET_SOFT_FLOAT)
> +        rust_add_target_info("target_feature", "soft-float");
> +    // should be correct option (i.e. thumb mode rather than just thumb-aware) as TARGET_ARM is
> +    // inverse
> +    if (TARGET_THUMB)
> +        rust_add_target_info("target_feature", "thumb-mode");
> +    // TODO: consider doing the processors as target features, but honestly they don't seem to fit
> +}
> diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
> index f479540812a..abaec9e71e6 100644
> --- a/gcc/config/arm/arm.h
> +++ b/gcc/config/arm/arm.h
> @@ -51,6 +51,9 @@ extern char arm_arch_name[];
>   #define TARGET_D_CPU_VERSIONS arm_d_target_versions
>   #define TARGET_D_REGISTER_CPU_TARGET_INFO arm_d_register_target_info
>   
> +/* Target CPU info for Rust.  */
> +#define TARGET_RUST_CPU_INFO arm_rust_target_cpu_info
> +
>   #include "config/arm/arm-opts.h"
>   
>   /* The processor for which instructions should be scheduled.  */
> diff --git a/gcc/config/arm/bpabi.h b/gcc/config/arm/bpabi.h
> index 70984ddd147..0df5dd0f31a 100644
> --- a/gcc/config/arm/bpabi.h
> +++ b/gcc/config/arm/bpabi.h
> @@ -104,6 +104,17 @@
>   #define TARGET_OS_CPP_BUILTINS() \
>     TARGET_BPABI_CPP_BUILTINS()
>   
> +#define BPABI_TARGET_RUST_OS_INFO() \
> +  do { \
> +    /*TODO: is this even an OS? What should go here?*/ \
> +  } while (0)
> +
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in bpabi.h - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO() \
> +  BPABI_TARGET_RUST_OS_INFO()
> +
>   /* The BPABI specifies the use of .{init,fini}_array.  Therefore, we
>      do not want GCC to put anything into the .{init,fini} sections.  */
>   #undef INIT_SECTION_ASM_OP
> diff --git a/gcc/config/arm/freebsd.h b/gcc/config/arm/freebsd.h
> index 2bd0dc97df3..d662ab005d6 100644
> --- a/gcc/config/arm/freebsd.h
> +++ b/gcc/config/arm/freebsd.h
> @@ -83,6 +83,15 @@
>       }						\
>     while (false)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in freebsd.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO() 		\
> +  do {						\
> +    FBSD_TARGET_RUST_OS_INFO ();		\
> +    BPABI_TARGET_RUST_OS_INFO ();		\
> +  } while (0)
> +
>   /* We default to a soft-float ABI so that binaries can run on all
>      target hardware.  */
>   #undef TARGET_DEFAULT_FLOAT_ABI
> diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
> index 50cc0bc6d08..a255ac0f1a7 100644
> --- a/gcc/config/arm/linux-eabi.h
> +++ b/gcc/config/arm/linux-eabi.h
> @@ -33,6 +33,14 @@
>   #define EXTRA_TARGET_D_OS_VERSIONS()		\
>     ANDROID_TARGET_D_OS_VERSIONS();
>   
> +#define EXTRA_TARGET_RUST_OS_INFO()		\
> +  do { 						\
> +    BPABI_TARGET_RUST_OS_INFO();		\
> +    GNU_USER_TARGET_RUST_OS_INFO();		\
> +    ANDROID_TARGET_RUST_OS_INFO();		\
> +    /*TODO: ensure that this makes target_os 'linux' properly and stuff*/ \
> +  while (0)
> +
>   /* We default to a soft-float ABI so that binaries can run on all
>      target hardware.  If you override this to use the hard-float ABI then
>      change the setting of GLIBC_DYNAMIC_LINKER_DEFAULT as well.  */
> diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
> index df3da67c4f0..0859945ed05 100644
> --- a/gcc/config/arm/linux-elf.h
> +++ b/gcc/config/arm/linux-elf.h
> @@ -83,6 +83,11 @@
>       }						\
>     while (0)
>   
> +#define TARGET_RUST_OS_INFO()		\
> +   do {						\
> +	   GNU_USER_TARGET_RUST_OS_INFO();	\
> +   } while (0)
> +
>   /* Call the function profiler with a given profile label.  */
>   #undef  ARM_FUNCTION_PROFILER
>   #define ARM_FUNCTION_PROFILER(STREAM, LABELNO)  			\
> diff --git a/gcc/config/arm/netbsd-eabi.h b/gcc/config/arm/netbsd-eabi.h
> index c85fcd3e385..a47b2ca3776 100644
> --- a/gcc/config/arm/netbsd-eabi.h
> +++ b/gcc/config/arm/netbsd-eabi.h
> @@ -64,6 +64,16 @@
>       }						\
>     while (0)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in netbsd-eabi.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()		\
> +  do {						\
> +  	if (TARGET_AAPCS_BASED)			\
> +      BPABI_TARGET_RUST_OS_INFO();		\
> +    NETBSD_TARGET_RUST_OS_INFO();		\
> +  } while (0)
> +
>   #undef SUBTARGET_CPP_SPEC
>   #define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
>   
> diff --git a/gcc/config/arm/netbsd-elf.h b/gcc/config/arm/netbsd-elf.h
> index d239c734c5c..e74cdcc6503 100644
> --- a/gcc/config/arm/netbsd-elf.h
> +++ b/gcc/config/arm/netbsd-elf.h
> @@ -51,6 +51,14 @@
>       }					\
>     while (0)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in netbsd-elf.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()	\
> +  do {					\
> +    NETBSD_TARGET_RUST_OS_INFO();	\
> +  } while (0)
> +
>   #undef SUBTARGET_CPP_SPEC
>   #define SUBTARGET_CPP_SPEC NETBSD_CPP_SPEC
>   
> diff --git a/gcc/config/arm/rtems.h b/gcc/config/arm/rtems.h
> index a569343451a..56f978bf73e 100644
> --- a/gcc/config/arm/rtems.h
> +++ b/gcc/config/arm/rtems.h
> @@ -33,4 +33,18 @@
>   	TARGET_BPABI_CPP_BUILTINS();    	\
>       } while (0)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in rtems.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()		\
> +  do {					\
> +    /*note: as far as I know, rustc has no supported for rtems, so this is just guessed*/ \
> +    /*everything is subject to change, especially target_env and target_family - TODO*/ \
> +    builtin_rust_info ("target_family", "unix");	\
> +    builtin_rust_info ("target_os", "rtems");	\
> +    builtin_rust_info ("target_vendor", "unknown");	\
> +    builtin_rust_info ("target_env", "");	\
> +    BPABI_TARGET_RUST_OS_INFO();	\
> +  } while (0)
> +
>   #define ARM_DEFAULT_SHORT_ENUMS false
> diff --git a/gcc/config/arm/symbian.h b/gcc/config/arm/symbian.h
> index 7df39170180..81c7cc00a27 100644
> --- a/gcc/config/arm/symbian.h
> +++ b/gcc/config/arm/symbian.h
> @@ -78,6 +78,21 @@
>       }								\
>     while (false)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in symbian.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()		\
> +  do {					\
> +    /*note: as far as I know, rustc has no supported for symbian, so this is just guessed*/ \
> +    /*everything is subject to change, especially target_env and target_vendor - TODO*/ \
> +    /*some triple examples i've seen are "arm-nokia-symbian-eabi" and possibly "arm-none-symbian-elf"*/ \
> +    builtin_rust_info ("target_family", "");	\
> +    builtin_rust_info ("target_os", "symbian");	\
> +    builtin_rust_info ("target_vendor", "unknown");	\
> +    builtin_rust_info ("target_env", "");	\
> +    BPABI_TARGET_RUST_OS_INFO();	\
> +  } while (0)
> +
>   /* On SymbianOS, these sections are not writable, so we use "a",
>      rather than "aw", for the section attributes.  */
>   #undef ARM_EABI_CTORS_SECTION_OP
> diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
> index 041cc6ec045..d093f3c789c 100644
> --- a/gcc/config/arm/t-arm
> +++ b/gcc/config/arm/t-arm
> @@ -172,6 +172,10 @@ arm-d.o: $(srcdir)/config/arm/arm-d.cc
>   	$(COMPILE) $<
>   	$(POSTCOMPILE)
>   
> +arm-rust.o: $(srcdir)/config/arm/arm-rust.cc
> +	$(COMPILE) $<
> +	$(POSTCOMPILE)
> +
>   arm-common.o: arm-cpu-cdata.h
>   
>   driver-arm.o: arm-native.h
> diff --git a/gcc/config/arm/uclinux-eabi.h b/gcc/config/arm/uclinux-eabi.h
> index 362d2b5ebd8..54bf78cdc0d 100644
> --- a/gcc/config/arm/uclinux-eabi.h
> +++ b/gcc/config/arm/uclinux-eabi.h
> @@ -46,6 +46,19 @@
>       }						\
>     while (false)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in uclinux-eabi.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()		\
> +  do {					\
> +    BPABI_TARGET_RUST_OS_INFO();	\
> +    /*note: as far as I know, rustc does not distinguish between uclinux and regular linux kernels*/ \
> +    builtin_rust_info ("target_family", "unix");	   \
> +    builtin_rust_info ("target_os", "linux");	      \
> +    builtin_rust_info ("target_vendor", "unknown");	\
> +    builtin_rust_info ("target_env", "gnu");	         \
> +  } while (0)
> +
>   #undef SUBTARGET_EXTRA_LINK_SPEC
>   #define SUBTARGET_EXTRA_LINK_SPEC " -m armelf_linux_eabi -elf2flt" \
>     " --pic-veneer --target2=abs"
> diff --git a/gcc/config/arm/uclinux-elf.h b/gcc/config/arm/uclinux-elf.h
> index 921440d49bd..3fcaf2d6acb 100644
> --- a/gcc/config/arm/uclinux-elf.h
> +++ b/gcc/config/arm/uclinux-elf.h
> @@ -48,6 +48,18 @@
>       }						\
>     while (false)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in uclinux-elf.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#define TARGET_RUST_OS_INFO()		\
> +  do {					\
> +    /*note: as far as I know, rustc does not distinguish between uclinux and regular linux kernels*/ \
> +    builtin_rust_info ("target_family", "unix");	   \
> +    builtin_rust_info ("target_os", "linux");	      \
> +    builtin_rust_info ("target_vendor", "unknown");	\
> +    builtin_rust_info ("target_env", "gnu");	         \
> +  } while (0)
> +
>   /* The GNU C++ standard library requires that these macros be defined.  */
>   #undef CPLUSPLUS_CPP_SPEC
>   #define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
> diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h
> index 2bcd01edc97..0d4989cb52a 100644
> --- a/gcc/config/arm/vxworks.h
> +++ b/gcc/config/arm/vxworks.h
> @@ -75,6 +75,20 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
>       MAYBE_TARGET_BPABI_CPP_BUILTINS ();			\
>     } while (0)
>   
> +#ifdef TARGET_RUST_OS_INFO
> +# error "TARGET_RUST_OS_INFO already defined in vxworks.h (arm) - c++ undefines it and redefines it."
> +#endif
> +#ifdef BPABI_TARGET_RUST_OS_INFO
> +# define MAYBE_BPABI_TARGET_RUST_OS_INFO BPABI_TARGET_RUST_OS_INFO
> +#else
> +# define MAYBE_BPABI_TARGET_RUST_OS_INFO()
> +#endif
> +#define TARGET_RUST_OS_INFO()			\
> +  do {			\
> +    VXWORKS_TARGET_RUST_OS_INFO ();			\
> +    MAYBE_BPABI_TARGET_RUST_OS_INFO ();			\
> +  } while (0)
> +
>   #undef SUBTARGET_OVERRIDE_OPTIONS
>   #define SUBTARGET_OVERRIDE_OPTIONS VXWORKS_OVERRIDE_OPTIONS
>   

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-07-27 13:40 Rust frontend patches v1 herron.philip
                   ` (2 preceding siblings ...)
  2022-07-27 13:40 ` [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM herron.philip
@ 2022-07-27 16:45 ` David Malcolm
  2022-07-28  9:39   ` Philip Herron
  3 siblings, 1 reply; 20+ messages in thread
From: David Malcolm @ 2022-07-27 16:45 UTC (permalink / raw)
  To: philip.herron, gcc-patches; +Cc: herron.philip

On Wed, 2022-07-27 at 14:40 +0100, herron.philip--- via Gcc-patches
wrote:
> This is the initial version 1 patch set for the Rust front-end. There
> are more changes that need to be extracted out for all the target
> hooks we have implemented. The goal is to see if we are implementing
> the target hooks information for x86 and arm. We have more patches
> for the other targets I can add in here but they all follow the
> pattern established here.
> 
> Each patch is buildable on its own and rebased ontop of
> 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we keep
> attribution for all the patches we have received in the front-end
> should we create a CONTRIBUTOR's file inside the front-end folder?
> 
> Note thanks to Thomas Schwinge and Mark Wielaard, we are keeping a
> branch up to date with our code on: 
> https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master
>  but this is not rebased ontop of gcc head.
> 
> Let me know if I have sent these patches correctly or not, this is a
> learning experience with git send-email.
> 
> [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
> [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and
> [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
> [PATCH Rust front-end v1 4/4] Add Rust front-end and associated

FWIW it looks like patch 4 of the kit didn't make it (I didn't get a
copy and I don't see it in the archives).

Maybe it exceeded a size limit?  If so, maybe try splitting it up into
more patches.

Dave


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-07-27 16:45 ` Rust frontend patches v1 David Malcolm
@ 2022-07-28  9:39   ` Philip Herron
  2022-08-10 18:56     ` Philip Herron
  0 siblings, 1 reply; 20+ messages in thread
From: Philip Herron @ 2022-07-28  9:39 UTC (permalink / raw)
  To: David Malcolm; +Cc: gcc-patches

Thanks, for confirming David. I think it was too big in the end. I was
trying to figure out how to actually split that up but it seems
reasonable that I can split up the front-end patches into patches for
each separate pass in the compiler seems like a reasonable approach
for now.

--Phil

On Wed, 27 Jul 2022 at 17:45, David Malcolm <dmalcolm@redhat.com> wrote:
>
> On Wed, 2022-07-27 at 14:40 +0100, herron.philip--- via Gcc-patches
> wrote:
> > This is the initial version 1 patch set for the Rust front-end. There
> > are more changes that need to be extracted out for all the target
> > hooks we have implemented. The goal is to see if we are implementing
> > the target hooks information for x86 and arm. We have more patches
> > for the other targets I can add in here but they all follow the
> > pattern established here.
> >
> > Each patch is buildable on its own and rebased ontop of
> > 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we keep
> > attribution for all the patches we have received in the front-end
> > should we create a CONTRIBUTOR's file inside the front-end folder?
> >
> > Note thanks to Thomas Schwinge and Mark Wielaard, we are keeping a
> > branch up to date with our code on:
> > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master
> >  but this is not rebased ontop of gcc head.
> >
> > Let me know if I have sent these patches correctly or not, this is a
> > learning experience with git send-email.
> >
> > [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
> > [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and
> > [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
> > [PATCH Rust front-end v1 4/4] Add Rust front-end and associated
>
> FWIW it looks like patch 4 of the kit didn't make it (I didn't get a
> copy and I don't see it in the archives).
>
> Maybe it exceeded a size limit?  If so, maybe try splitting it up into
> more patches.
>
> Dave
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-27 13:40 ` [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 herron.philip
@ 2022-07-28  9:57   ` Jakub Jelinek
  2022-07-28 10:38   ` Thomas Schwinge
  1 sibling, 0 replies; 20+ messages in thread
From: Jakub Jelinek @ 2022-07-28  9:57 UTC (permalink / raw)
  To: philip.herron; +Cc: gcc-patches, herron.philip, SimplyTheOther

Note, the ChangeLog entry formatting is wrong and in various places
the code formatting as well.  In gcc/rust/ you can choose different
formatting if there are strong reasons for that, but at least it should be
consistent and ideally documented.

None of the gcc/doc, gcc/config, gcc/config/i386 directories have
ChangeLog files, so all this should go into gcc/ChangeLog
and filenames should be relative to the gcc/ directory, so
doc/tm.texi.in, config/default-rust.cc, config/i386/crtdll.h etc.

After : there should be a capital letter and the description what
changed should end with a dot.
Where possible, before : there should be space ( followed by what
has changed followed by ).
When some file is regenerated, just write Regenerated. or so.
When a new file is added, just write New. or New file.

On Wed, Jul 27, 2022 at 02:40:38PM +0100, herron.philip--- via Gcc-patches wrote:
> gcc/doc/ChangeLog:
> 
>         * tm.texi.in: specifiy hooks for rust target info
>         * tm.texi: commit the generated documentation
> 
> gcc/ChangeLog:
> 
>         * Makefile.in: add target to generate rust hooks
>         * config.gcc: add rust target interface to be compiled for i386
> 	* genhooks.cc: generate rust target hooks
> 	* configure: autoconf update
> 	* configure.ac: add tm_rust_file_list and tm_rust_include_list
> 
> gcc/config/ChangeLog:
> 
>         * default-rust.cc: new target hooks initializer for rust
>         * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
> 	* dragonfly.h: define TARGET_RUST_OS_INFO
> 	* freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
> 	* freebsd.h: define guard for TARGET_RUST_OS_INFO
> 	* fuchsia.h: define TARGET_RUST_OS_INFO
> 	* kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> 	* kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> 	* linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
> 	* linux.h: define GNU_USER_TARGET_RUST_OS_INFO
> 	* netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
> 	* openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
> 	* phoenix.h: define TARGET_RUST_OS_INFO
> 	* sol2.h: define TARGET_RUST_OS_INFO
> 	* vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
> 	* vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO
> 
> gcc/config/i386/ChangeLog:
> 
>         * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
>         * cygming.h: define TARGET_RUST_OS_INFO
>         * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
>         * darwin.h: define TARGET_RUST_OS_INFO
>         * djgpp.h: likewise
>         * gnu-user-common.h: define TARGET_RUST_OS_INFO
>         * i386-protos.h: prototype for ix86_rust_target_cpu_info
>         * i386-rust.cc: new file to generate the rust target host info
>         * i386.h: define TARGET_RUST_CPU_INFO hook
>         * linux-common.h: define hooks for target info
>         * lynx.h: likewise
>         * mingw32.h: likewise
>         * netbsd-elf.h: likewise
>         * netbsd64.h: likewise
>         * nto.h: likewise
>         * openbsdelf.h: likewise
>         * rdos.h: likewise
>         * rtemself.h: likewise
>         * t-i386: add makefilke rule for i386-rust.cc
>         * vxworks.h: define TARGET_RUST_OS_INFO
> 
> gcc/rust/ChangeLog:
> 
>         * rust-target-def.h: define the headers to access the hooks
>         * rust-target.def: define the hooks nessecary based on C90
>         * rust-target.h: define extern gcc_targetrustm
> +/* Implement TARGET_RUST_CPU_INFO for x86 targets.  */
> +
> +void
> +ix86_rust_target_cpu_info (void)
> +{
> +    if (TARGET_64BIT) {
> +        rust_add_target_info("target_arch", "x86_64");

The indentation should be just 2 columns rather than 4, and
{ doesn't go at the end of line.  Single statement if/else/etc.
bodies aren't wrapped with {}s.  There is space before (.
So
  if (TARGET_64BIT)
    {
      rust_add_target_info ("target_arch", "x86_64");
      ...
    }
  else
    rust_add_target_info ("target_arch", "x86");

> +  // nopl: hard-coded (as gcc doesn't technically have feature) to return true for cpu arches with it
> +  // maybe refactor into switch if multiple options
> +  bool hasNOPL = ix86_arch == PROCESSOR_PENTIUMPRO || ix86_arch == PROCESSOR_PENTIUM4 
> +    || ix86_arch == PROCESSOR_NOCONA || ix86_arch == PROCESSOR_CORE2 || ix86_arch == PROCESSOR_NEHALEM 

Some lines are too long.

	Jakub


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-27 13:40 ` [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 herron.philip
  2022-07-28  9:57   ` Jakub Jelinek
@ 2022-07-28 10:38   ` Thomas Schwinge
  2022-07-28 10:51     ` Philip Herron
  1 sibling, 1 reply; 20+ messages in thread
From: Thomas Schwinge @ 2022-07-28 10:38 UTC (permalink / raw)
  To: Philip Herron, gcc-patches; +Cc: herron.philip, SimplyTheOther

[-- Attachment #1: Type: text/plain, Size: 4541 bytes --]

Hi!

On 2022-07-27T14:40:38+0100, "herron.philip--- via Gcc-patches" <gcc-patches@gcc.gnu.org> wrote:
> This patch introduces a new set of interfaces to define the target info as
> expected by the rust front-end. It takes advantage of the information
> within gcc/config/target directories which gets called by the front-end
> to populate rust front-end datastructures by calling into:
> builtin_rust_info. This patch has been isolated to find if we are
> approaching this in an idiomatic way and is compilable without the
> rust-front-end code.

I suppose the general approach may be fine, as is similarly implemented
by other languages' front ends in GCC.

> We have received many patches here which gives us the target hook info for
> most platforms

But this is all so much WIP and full of TODO notes, and has no test cases
at all!, that I still don't really see much value in keeping the current
implementations of 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc.
Applying "[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'"
that I've attached, we're not seeing any change in 'make check-rust'
results, for example.

In my opinion, the current implementation should be backed out from the
main development branch (would also reduce pain in merges from GCC
upstream, as mentioned before), and then be developed (quite possibly
based on the current implementation) individually for all GCC
configurations that we'd like to support (with 'sorry' otherwise), in a
coherent way, instead of trying to guess all possible target options as
done by the current implementation.  And, with all relevant test cases
getting added, of course.  That is, at this time, restrict outselves to
GCC configurations that we're actually supporting and testing.

Have we even figured out which of those target options are actually
mandated for a conforming Rust programming language implementation (that
is, users would potentially rely on these)?

As far as I can tell, 'rustc' defines target options here:
<https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec>,
and you may use 'rustc --print=cfg' to dump for the current
configuration?

> but getting the normal x86 done correctly will define if
> the other patches are done correctly.

Yes -- but I'm not sure this is it really, in its current WIPy,
un-tested, un-verified form:

> gcc/config/ChangeLog:

>         * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
>       * dragonfly.h: define TARGET_RUST_OS_INFO
>       * freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
>       * freebsd.h: define guard for TARGET_RUST_OS_INFO
>       * fuchsia.h: define TARGET_RUST_OS_INFO
>       * kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
>       * kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
>       * linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
>       * linux.h: define GNU_USER_TARGET_RUST_OS_INFO
>       * netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
>       * openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
>       * phoenix.h: define TARGET_RUST_OS_INFO
>       * sol2.h: define TARGET_RUST_OS_INFO
>       * vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
>       * vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO
>
> gcc/config/i386/ChangeLog:
>
>         * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
>         * cygming.h: define TARGET_RUST_OS_INFO
>         * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
>         * darwin.h: define TARGET_RUST_OS_INFO
>         * djgpp.h: likewise
>         * gnu-user-common.h: define TARGET_RUST_OS_INFO
>         * i386-protos.h: prototype for ix86_rust_target_cpu_info
>         * i386-rust.cc: new file to generate the rust target host info
>         * i386.h: define TARGET_RUST_CPU_INFO hook
>         * linux-common.h: define hooks for target info
>         * lynx.h: likewise
>         * mingw32.h: likewise
>         * netbsd-elf.h: likewise
>         * netbsd64.h: likewise
>         * nto.h: likewise
>         * openbsdelf.h: likewise
>         * rdos.h: likewise
>         * rtemself.h: likewise
>         * t-i386: add makefilke rule for i386-rust.cc
>         * vxworks.h: define TARGET_RUST_OS_INFO


Grüße
 Thomas


-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-HACK-Disable-TARGET_RUST_CPU_INFO-TARGET_RUST_OS_INF.patch --]
[-- Type: text/x-diff, Size: 1780 bytes --]

From a5688c5da3c9ffda614f4138e55f46b7078b9e3a Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <thomas@codesourcery.com>
Date: Thu, 28 Jul 2022 12:04:28 +0200
Subject: [PATCH] [HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'

---
 gcc/rust/rust-lang.cc            | 2 ++
 gcc/rust/rust-session-manager.cc | 6 ++++++
 2 files changed, 8 insertions(+)

diff --git a/gcc/rust/rust-lang.cc b/gcc/rust/rust-lang.cc
index dd8c608789a..40331f6a431 100644
--- a/gcc/rust/rust-lang.cc
+++ b/gcc/rust/rust-lang.cc
@@ -107,6 +107,8 @@ struct GTY (()) language_function
 void
 rust_add_target_info (const char *key, const char *value)
 {
+  sorry("TODO");
+
   Rust::Session::get_instance ().options.target_data.insert_key_value_pair (
     key, value);
 }
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index 6a2c1b6dd62..d41dc18fa00 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -134,6 +134,8 @@ validate_crate_name (const std::string &crate_name, Error &error)
 void
 Session::implicitly_enable_feature (std::string feature_name)
 {
+  sorry("TODO");
+
   // TODO: is this really required since features added would be complete via
   // target spec?
 
@@ -195,6 +197,8 @@ Session::implicitly_enable_feature (std::string feature_name)
 void
 Session::enable_features ()
 {
+  sorry("TODO");
+
   bool has_target_crt_static = false;
 
   rust_debug (
@@ -335,6 +339,7 @@ Session::enable_features ()
 void
 Session::init ()
 {
+#if 0
 #ifndef TARGET_RUST_OS_INFO
 #define TARGET_RUST_OS_INFO()
 #endif
@@ -379,6 +384,7 @@ Session::init ()
 
   // derived values from hook
   options.target_data.init_derived_values ();
+#endif
 
   // setup singleton linemap
   linemap = rust_get_linemap ();
-- 
2.35.1


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-28 10:38   ` Thomas Schwinge
@ 2022-07-28 10:51     ` Philip Herron
  2022-07-28 11:08       ` Thomas Schwinge
  0 siblings, 1 reply; 20+ messages in thread
From: Philip Herron @ 2022-07-28 10:51 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: gcc-patches, Philip Herron, SimplyTheOther

Hi Thomas,

I think you are right here. There are parts in
libstd/liballoc/libpanic which start to look for what CPU features are
available iirc. Maintaining our patches here has been becoming
difficult as of late, especially when it comes to libcore, which just
cares about target pointer width and endienness which is more
generally available as macros.

It seems more clear now that maybe for this v1 set of patches,
possibly this stuff doesn't really matter right now until we compile
libstd which seems like a much better approach in order to review the
front-end code. I think i will apply your patch and revert these
changes for now since we have the git history for them we can look at
this more closely when we need it.

Thanks

--Phil


On Thu, 28 Jul 2022 at 11:38, Thomas Schwinge <thomas@codesourcery.com> wrote:
>
> Hi!
>
> On 2022-07-27T14:40:38+0100, "herron.philip--- via Gcc-patches" <gcc-patches@gcc.gnu.org> wrote:
> > This patch introduces a new set of interfaces to define the target info as
> > expected by the rust front-end. It takes advantage of the information
> > within gcc/config/target directories which gets called by the front-end
> > to populate rust front-end datastructures by calling into:
> > builtin_rust_info. This patch has been isolated to find if we are
> > approaching this in an idiomatic way and is compilable without the
> > rust-front-end code.
>
> I suppose the general approach may be fine, as is similarly implemented
> by other languages' front ends in GCC.
>
> > We have received many patches here which gives us the target hook info for
> > most platforms
>
> But this is all so much WIP and full of TODO notes, and has no test cases
> at all!, that I still don't really see much value in keeping the current
> implementations of 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc.
> Applying "[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'"
> that I've attached, we're not seeing any change in 'make check-rust'
> results, for example.
>
> In my opinion, the current implementation should be backed out from the
> main development branch (would also reduce pain in merges from GCC
> upstream, as mentioned before), and then be developed (quite possibly
> based on the current implementation) individually for all GCC
> configurations that we'd like to support (with 'sorry' otherwise), in a
> coherent way, instead of trying to guess all possible target options as
> done by the current implementation.  And, with all relevant test cases
> getting added, of course.  That is, at this time, restrict outselves to
> GCC configurations that we're actually supporting and testing.
>
> Have we even figured out which of those target options are actually
> mandated for a conforming Rust programming language implementation (that
> is, users would potentially rely on these)?
>
> As far as I can tell, 'rustc' defines target options here:
> <https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec>,
> and you may use 'rustc --print=cfg' to dump for the current
> configuration?
>
> > but getting the normal x86 done correctly will define if
> > the other patches are done correctly.
>
> Yes -- but I'm not sure this is it really, in its current WIPy,
> un-tested, un-verified form:
>
> > gcc/config/ChangeLog:
>
> >         * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
> >       * dragonfly.h: define TARGET_RUST_OS_INFO
> >       * freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
> >       * freebsd.h: define guard for TARGET_RUST_OS_INFO
> >       * fuchsia.h: define TARGET_RUST_OS_INFO
> >       * kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> >       * kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> >       * linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
> >       * linux.h: define GNU_USER_TARGET_RUST_OS_INFO
> >       * netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
> >       * openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
> >       * phoenix.h: define TARGET_RUST_OS_INFO
> >       * sol2.h: define TARGET_RUST_OS_INFO
> >       * vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
> >       * vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO
> >
> > gcc/config/i386/ChangeLog:
> >
> >         * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
> >         * cygming.h: define TARGET_RUST_OS_INFO
> >         * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
> >         * darwin.h: define TARGET_RUST_OS_INFO
> >         * djgpp.h: likewise
> >         * gnu-user-common.h: define TARGET_RUST_OS_INFO
> >         * i386-protos.h: prototype for ix86_rust_target_cpu_info
> >         * i386-rust.cc: new file to generate the rust target host info
> >         * i386.h: define TARGET_RUST_CPU_INFO hook
> >         * linux-common.h: define hooks for target info
> >         * lynx.h: likewise
> >         * mingw32.h: likewise
> >         * netbsd-elf.h: likewise
> >         * netbsd64.h: likewise
> >         * nto.h: likewise
> >         * openbsdelf.h: likewise
> >         * rdos.h: likewise
> >         * rtemself.h: likewise
> >         * t-i386: add makefilke rule for i386-rust.cc
> >         * vxworks.h: define TARGET_RUST_OS_INFO
>
>
> Grüße
>  Thomas
>
>
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-28 10:51     ` Philip Herron
@ 2022-07-28 11:08       ` Thomas Schwinge
  2022-07-28 11:41         ` Philip Herron
  0 siblings, 1 reply; 20+ messages in thread
From: Thomas Schwinge @ 2022-07-28 11:08 UTC (permalink / raw)
  To: Philip Herron; +Cc: gcc-patches, Philip Herron, SimplyTheOther

Hi Phil!

On 2022-07-28T11:51:37+0100, Philip Herron <philip.herron@embecosm.com> wrote:
> I think you are right here. There are parts in
> libstd/liballoc/libpanic which start to look for what CPU features are
> available iirc.

Aha, good.  That -- once we get there ;-) -- shall then guide us on the
target options we implement, in addition to what we find generally
necessary for a conforming Rust programming language implementation (as
I'd mentioned).

> libcore [...] just
> cares about target pointer width and endienness which is more
> generally available as macros.

Right, and these are already implemented in
'gcc/rust/rust-session-manager.cc:Session::init'.  (..., but also should
get some test cases added; I'll have a look at some point.)

> It seems more clear now that maybe for this v1 set of patches,
> possibly this stuff doesn't really matter right now until we compile
> libstd which seems like a much better approach in order to review the
> front-end code. I think i will apply your patch and revert these
> changes for now since we have the git history for them we can look at
> this more closely when we need it.

Unless this issue is time-critical, let me offer that instead of my
"[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'",
I'll cook up a proper patch, removing the implementations of
'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc., but keeping the
general infrastructure in place (if I find that makes sense)?


Grüße
 Thomas


> On Thu, 28 Jul 2022 at 11:38, Thomas Schwinge <thomas@codesourcery.com> wrote:
>>
>> Hi!
>>
>> On 2022-07-27T14:40:38+0100, "herron.philip--- via Gcc-patches" <gcc-patches@gcc.gnu.org> wrote:
>> > This patch introduces a new set of interfaces to define the target info as
>> > expected by the rust front-end. It takes advantage of the information
>> > within gcc/config/target directories which gets called by the front-end
>> > to populate rust front-end datastructures by calling into:
>> > builtin_rust_info. This patch has been isolated to find if we are
>> > approaching this in an idiomatic way and is compilable without the
>> > rust-front-end code.
>>
>> I suppose the general approach may be fine, as is similarly implemented
>> by other languages' front ends in GCC.
>>
>> > We have received many patches here which gives us the target hook info for
>> > most platforms
>>
>> But this is all so much WIP and full of TODO notes, and has no test cases
>> at all!, that I still don't really see much value in keeping the current
>> implementations of 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc.
>> Applying "[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'"
>> that I've attached, we're not seeing any change in 'make check-rust'
>> results, for example.
>>
>> In my opinion, the current implementation should be backed out from the
>> main development branch (would also reduce pain in merges from GCC
>> upstream, as mentioned before), and then be developed (quite possibly
>> based on the current implementation) individually for all GCC
>> configurations that we'd like to support (with 'sorry' otherwise), in a
>> coherent way, instead of trying to guess all possible target options as
>> done by the current implementation.  And, with all relevant test cases
>> getting added, of course.  That is, at this time, restrict outselves to
>> GCC configurations that we're actually supporting and testing.
>>
>> Have we even figured out which of those target options are actually
>> mandated for a conforming Rust programming language implementation (that
>> is, users would potentially rely on these)?
>>
>> As far as I can tell, 'rustc' defines target options here:
>> <https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec>,
>> and you may use 'rustc --print=cfg' to dump for the current
>> configuration?
>>
>> > but getting the normal x86 done correctly will define if
>> > the other patches are done correctly.
>>
>> Yes -- but I'm not sure this is it really, in its current WIPy,
>> un-tested, un-verified form:
>>
>> > gcc/config/ChangeLog:
>>
>> >         * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
>> >       * dragonfly.h: define TARGET_RUST_OS_INFO
>> >       * freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
>> >       * freebsd.h: define guard for TARGET_RUST_OS_INFO
>> >       * fuchsia.h: define TARGET_RUST_OS_INFO
>> >       * kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
>> >       * kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
>> >       * linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
>> >       * linux.h: define GNU_USER_TARGET_RUST_OS_INFO
>> >       * netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
>> >       * openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
>> >       * phoenix.h: define TARGET_RUST_OS_INFO
>> >       * sol2.h: define TARGET_RUST_OS_INFO
>> >       * vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
>> >       * vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO
>> >
>> > gcc/config/i386/ChangeLog:
>> >
>> >         * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
>> >         * cygming.h: define TARGET_RUST_OS_INFO
>> >         * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
>> >         * darwin.h: define TARGET_RUST_OS_INFO
>> >         * djgpp.h: likewise
>> >         * gnu-user-common.h: define TARGET_RUST_OS_INFO
>> >         * i386-protos.h: prototype for ix86_rust_target_cpu_info
>> >         * i386-rust.cc: new file to generate the rust target host info
>> >         * i386.h: define TARGET_RUST_CPU_INFO hook
>> >         * linux-common.h: define hooks for target info
>> >         * lynx.h: likewise
>> >         * mingw32.h: likewise
>> >         * netbsd-elf.h: likewise
>> >         * netbsd64.h: likewise
>> >         * nto.h: likewise
>> >         * openbsdelf.h: likewise
>> >         * rdos.h: likewise
>> >         * rtemself.h: likewise
>> >         * t-i386: add makefilke rule for i386-rust.cc
>> >         * vxworks.h: define TARGET_RUST_OS_INFO
>>
>>
>> Grüße
>>  Thomas
>>
>>
>> -----------------
>> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64
  2022-07-28 11:08       ` Thomas Schwinge
@ 2022-07-28 11:41         ` Philip Herron
  0 siblings, 0 replies; 20+ messages in thread
From: Philip Herron @ 2022-07-28 11:41 UTC (permalink / raw)
  To: Thomas Schwinge; +Cc: gcc-patches, Philip Herron, SimplyTheOther

That would be brilliant if you could do that! I can spend my time
focused on splitting the front-end into patches. In the meantime,
while you work on that, I will use your patch here to disable the
target hook stuff so that the patches are buildable.

--Phil

On Thu, 28 Jul 2022 at 12:09, Thomas Schwinge <thomas@codesourcery.com> wrote:
>
> Hi Phil!
>
> On 2022-07-28T11:51:37+0100, Philip Herron <philip.herron@embecosm.com> wrote:
> > I think you are right here. There are parts in
> > libstd/liballoc/libpanic which start to look for what CPU features are
> > available iirc.
>
> Aha, good.  That -- once we get there ;-) -- shall then guide us on the
> target options we implement, in addition to what we find generally
> necessary for a conforming Rust programming language implementation (as
> I'd mentioned).
>
> > libcore [...] just
> > cares about target pointer width and endienness which is more
> > generally available as macros.
>
> Right, and these are already implemented in
> 'gcc/rust/rust-session-manager.cc:Session::init'.  (..., but also should
> get some test cases added; I'll have a look at some point.)
>
> > It seems more clear now that maybe for this v1 set of patches,
> > possibly this stuff doesn't really matter right now until we compile
> > libstd which seems like a much better approach in order to review the
> > front-end code. I think i will apply your patch and revert these
> > changes for now since we have the git history for them we can look at
> > this more closely when we need it.
>
> Unless this issue is time-critical, let me offer that instead of my
> "[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'",
> I'll cook up a proper patch, removing the implementations of
> 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc., but keeping the
> general infrastructure in place (if I find that makes sense)?
>
>
> Grüße
>  Thomas
>
>
> > On Thu, 28 Jul 2022 at 11:38, Thomas Schwinge <thomas@codesourcery.com> wrote:
> >>
> >> Hi!
> >>
> >> On 2022-07-27T14:40:38+0100, "herron.philip--- via Gcc-patches" <gcc-patches@gcc.gnu.org> wrote:
> >> > This patch introduces a new set of interfaces to define the target info as
> >> > expected by the rust front-end. It takes advantage of the information
> >> > within gcc/config/target directories which gets called by the front-end
> >> > to populate rust front-end datastructures by calling into:
> >> > builtin_rust_info. This patch has been isolated to find if we are
> >> > approaching this in an idiomatic way and is compilable without the
> >> > rust-front-end code.
> >>
> >> I suppose the general approach may be fine, as is similarly implemented
> >> by other languages' front ends in GCC.
> >>
> >> > We have received many patches here which gives us the target hook info for
> >> > most platforms
> >>
> >> But this is all so much WIP and full of TODO notes, and has no test cases
> >> at all!, that I still don't really see much value in keeping the current
> >> implementations of 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO', etc.
> >> Applying "[HACK] Disable 'TARGET_RUST_CPU_INFO', 'TARGET_RUST_OS_INFO'"
> >> that I've attached, we're not seeing any change in 'make check-rust'
> >> results, for example.
> >>
> >> In my opinion, the current implementation should be backed out from the
> >> main development branch (would also reduce pain in merges from GCC
> >> upstream, as mentioned before), and then be developed (quite possibly
> >> based on the current implementation) individually for all GCC
> >> configurations that we'd like to support (with 'sorry' otherwise), in a
> >> coherent way, instead of trying to guess all possible target options as
> >> done by the current implementation.  And, with all relevant test cases
> >> getting added, of course.  That is, at this time, restrict outselves to
> >> GCC configurations that we're actually supporting and testing.
> >>
> >> Have we even figured out which of those target options are actually
> >> mandated for a conforming Rust programming language implementation (that
> >> is, users would potentially rely on these)?
> >>
> >> As far as I can tell, 'rustc' defines target options here:
> >> <https://github.com/rust-lang/rust/tree/master/compiler/rustc_target/src/spec>,
> >> and you may use 'rustc --print=cfg' to dump for the current
> >> configuration?
> >>
> >> > but getting the normal x86 done correctly will define if
> >> > the other patches are done correctly.
> >>
> >> Yes -- but I'm not sure this is it really, in its current WIPy,
> >> un-tested, un-verified form:
> >>
> >> > gcc/config/ChangeLog:
> >>
> >> >         * gnu.h: add new macro GNU_USER_TARGET_RUST_OS_INFO
> >> >       * dragonfly.h: define TARGET_RUST_OS_INFO
> >> >       * freebsd-spec.h: define FBSD_TARGET_RUST_OS_INFO
> >> >       * freebsd.h: define guard for TARGET_RUST_OS_INFO
> >> >       * fuchsia.h: define TARGET_RUST_OS_INFO
> >> >       * kfreebsd-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> >> >       * kopensolaris-gnu.h: define GNU_USER_TARGET_RUST_OS_INFO
> >> >       * linux-android.h: define ANDROID_TARGET_RUST_OS_INFO
> >> >       * linux.h: define GNU_USER_TARGET_RUST_OS_INFO
> >> >       * netbsd.h: define NETBSD_TARGET_RUST_OS_INFO
> >> >       * openbsd.h: define OPENBSD_TARGET_RUST_OS_INFO
> >> >       * phoenix.h: define TARGET_RUST_OS_INFO
> >> >       * sol2.h: define TARGET_RUST_OS_INFO
> >> >       * vxworks.h: define VXWORKS_TARGET_RUST_OS_INFO
> >> >       * vxworksae.h: define VXWORKS_TARGET_RUST_OS_INFO
> >> >
> >> > gcc/config/i386/ChangeLog:
> >> >
> >> >         * crtdll.h: define EXTRA_TARGET_RUST_OS_INFO
> >> >         * cygming.h: define TARGET_RUST_OS_INFO
> >> >         * cygwin.h: define EXTRA_TARGET_RUST_OS_INFO
> >> >         * darwin.h: define TARGET_RUST_OS_INFO
> >> >         * djgpp.h: likewise
> >> >         * gnu-user-common.h: define TARGET_RUST_OS_INFO
> >> >         * i386-protos.h: prototype for ix86_rust_target_cpu_info
> >> >         * i386-rust.cc: new file to generate the rust target host info
> >> >         * i386.h: define TARGET_RUST_CPU_INFO hook
> >> >         * linux-common.h: define hooks for target info
> >> >         * lynx.h: likewise
> >> >         * mingw32.h: likewise
> >> >         * netbsd-elf.h: likewise
> >> >         * netbsd64.h: likewise
> >> >         * nto.h: likewise
> >> >         * openbsdelf.h: likewise
> >> >         * rdos.h: likewise
> >> >         * rtemself.h: likewise
> >> >         * t-i386: add makefilke rule for i386-rust.cc
> >> >         * vxworks.h: define TARGET_RUST_OS_INFO
> >>
> >>
> >> Grüße
> >>  Thomas
> >>
> >>
> >> -----------------
> >> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955
> -----------------
> Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht München, HRB 106955

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-07-28  9:39   ` Philip Herron
@ 2022-08-10 18:56     ` Philip Herron
  2022-08-10 19:06       ` David Malcolm
                         ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Philip Herron @ 2022-08-10 18:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: manu, David Malcolm

Hi everyone

For my v2 of the patches, I've been spending a lot of time ensuring
each patch is buildable. It would end up being simpler if it was
possible if each patch did not have to be like this so I could split
up the front-end in more patches. Does this make sense? In theory,
when everything goes well, does this still mean that we can merge in
one commit, or should it follow a series of buildable patches? I've
received feedback that it might be possible to ignore making each
patch an independent chunk and just focus on splitting it up as small
as possible even if they don't build.

I hope this makes sense.

Thanks

--Phil

On Thu, 28 Jul 2022 at 10:39, Philip Herron <philip.herron@embecosm.com> wrote:
>
> Thanks, for confirming David. I think it was too big in the end. I was
> trying to figure out how to actually split that up but it seems
> reasonable that I can split up the front-end patches into patches for
> each separate pass in the compiler seems like a reasonable approach
> for now.
>
> --Phil
>
> On Wed, 27 Jul 2022 at 17:45, David Malcolm <dmalcolm@redhat.com> wrote:
> >
> > On Wed, 2022-07-27 at 14:40 +0100, herron.philip--- via Gcc-patches
> > wrote:
> > > This is the initial version 1 patch set for the Rust front-end. There
> > > are more changes that need to be extracted out for all the target
> > > hooks we have implemented. The goal is to see if we are implementing
> > > the target hooks information for x86 and arm. We have more patches
> > > for the other targets I can add in here but they all follow the
> > > pattern established here.
> > >
> > > Each patch is buildable on its own and rebased ontop of
> > > 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we keep
> > > attribution for all the patches we have received in the front-end
> > > should we create a CONTRIBUTOR's file inside the front-end folder?
> > >
> > > Note thanks to Thomas Schwinge and Mark Wielaard, we are keeping a
> > > branch up to date with our code on:
> > > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master
> > >  but this is not rebased ontop of gcc head.
> > >
> > > Let me know if I have sent these patches correctly or not, this is a
> > > learning experience with git send-email.
> > >
> > > [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
> > > [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and
> > > [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
> > > [PATCH Rust front-end v1 4/4] Add Rust front-end and associated
> >
> > FWIW it looks like patch 4 of the kit didn't make it (I didn't get a
> > copy and I don't see it in the archives).
> >
> > Maybe it exceeded a size limit?  If so, maybe try splitting it up into
> > more patches.
> >
> > Dave
> >

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-10 18:56     ` Philip Herron
@ 2022-08-10 19:06       ` David Malcolm
  2022-08-12 20:45       ` Mike Stump
  2022-08-15 14:07       ` Manuel López-Ibáñez
  2 siblings, 0 replies; 20+ messages in thread
From: David Malcolm @ 2022-08-10 19:06 UTC (permalink / raw)
  To: Philip Herron, gcc-patches; +Cc: manu

On Wed, 2022-08-10 at 19:56 +0100, Philip Herron wrote:
> Hi everyone
> 
> For my v2 of the patches, I've been spending a lot of time ensuring
> each patch is buildable. It would end up being simpler if it was
> possible if each patch did not have to be like this so I could split
> up the front-end in more patches. Does this make sense?

Yes.  I've often split up patches into chunks when posting them for
review, and I see other people here do that.

It makes it easier for the reviewer also, since it's usually easier to
deal with e.g. 10 small patches than one enormous one (e.g. if many of
them are uncontroversial, having them split up makes it easier to focus
attention on just the controversial areas).

>  In theory,
> when everything goes well, does this still mean that we can merge in
> one commit, 

Split up the patches for review, but make a note in the cover letter
than they would all be merged into one when committing.

(especially if doing the split is taking up a lot of time; we don't
want to be mandating busy-work)

Dave


> or should it follow a series of buildable patches? I've
> received feedback that it might be possible to ignore making each
> patch an independent chunk and just focus on splitting it up as small
> as possible even if they don't build.
> 
> I hope this makes sense.
> 
> Thanks
> 
> --Phil
> 
> On Thu, 28 Jul 2022 at 10:39, Philip Herron < 
> philip.herron@embecosm.com> wrote:
> > 
> > Thanks, for confirming David. I think it was too big in the end. I
> > was
> > trying to figure out how to actually split that up but it seems
> > reasonable that I can split up the front-end patches into patches
> > for
> > each separate pass in the compiler seems like a reasonable approach
> > for now.
> > 
> > --Phil
> > 
> > On Wed, 27 Jul 2022 at 17:45, David Malcolm <dmalcolm@redhat.com>
> > wrote:
> > > 
> > > On Wed, 2022-07-27 at 14:40 +0100, herron.philip--- via Gcc-
> > > patches
> > > wrote:
> > > > This is the initial version 1 patch set for the Rust front-end.
> > > > There
> > > > are more changes that need to be extracted out for all the
> > > > target
> > > > hooks we have implemented. The goal is to see if we are
> > > > implementing
> > > > the target hooks information for x86 and arm. We have more
> > > > patches
> > > > for the other targets I can add in here but they all follow the
> > > > pattern established here.
> > > > 
> > > > Each patch is buildable on its own and rebased ontop of
> > > > 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we
> > > > keep
> > > > attribution for all the patches we have received in the front-
> > > > end
> > > > should we create a CONTRIBUTOR's file inside the front-end
> > > > folder?
> > > > 
> > > > Note thanks to Thomas Schwinge and Mark Wielaard, we are
> > > > keeping a
> > > > branch up to date with our code on:
> > > >  
> > > > https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master
> > > >  but this is not rebased ontop of gcc head.
> > > > 
> > > > Let me know if I have sent these patches correctly or not, this
> > > > is a
> > > > learning experience with git send-email.
> > > > 
> > > > [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end
> > > > folder
> > > > [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for
> > > > i386 and
> > > > [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
> > > > [PATCH Rust front-end v1 4/4] Add Rust front-end and associated
> > > 
> > > FWIW it looks like patch 4 of the kit didn't make it (I didn't
> > > get a
> > > copy and I don't see it in the archives).
> > > 
> > > Maybe it exceeded a size limit?  If so, maybe try splitting it up
> > > into
> > > more patches.
> > > 
> > > Dave
> > > 
> 



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-10 18:56     ` Philip Herron
  2022-08-10 19:06       ` David Malcolm
@ 2022-08-12 20:45       ` Mike Stump
  2022-08-15 14:07       ` Manuel López-Ibáñez
  2 siblings, 0 replies; 20+ messages in thread
From: Mike Stump @ 2022-08-12 20:45 UTC (permalink / raw)
  To: Philip Herron; +Cc: gcc-patches, manu

On Aug 10, 2022, at 11:56 AM, Philip Herron <philip.herron@embecosm.com> wrote:
> 
> For my v2 of the patches, I've been spending a lot of time ensuring
> each patch is buildable. It would end up being simpler if it was
> possible if each patch did not have to be like this so I could split
> up the front-end in more patches. Does this make sense? In theory,
> when everything goes well, does this still mean that we can merge in
> one commit, or should it follow a series of buildable patches? I've
> received feedback that it might be possible to ignore making each
> patch an independent chunk and just focus on splitting it up as small
> as possible even if they don't build.

It is a waste of time to make each build.  The all go in together, or not at all.  The patches are split for review only.  You can then maintain approval status for each individually and perform adjustments and updates for each patch.

Once all pieces have been approved in their final form, you can then commit the whole at once.  It is this commit, before you commit, that you regression test, integration test, and ensure that final form is good.  If not, you bounce back to update for all the pieces that need it, approval for those edits, and lather, rinse, repeat.

It is handy for larger work (like this) to be on a git branch so that followers can see the totality of the work and experiment with it in the large.  I'd usually do the commit to the main branch as a squashed commit without the review edit histories or the "bad stuff" the reviewers had you change or the merge records even.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-10 18:56     ` Philip Herron
  2022-08-10 19:06       ` David Malcolm
  2022-08-12 20:45       ` Mike Stump
@ 2022-08-15 14:07       ` Manuel López-Ibáñez
  2022-08-15 14:33         ` Martin Liška
  2 siblings, 1 reply; 20+ messages in thread
From: Manuel López-Ibáñez @ 2022-08-15 14:07 UTC (permalink / raw)
  To: Philip Herron; +Cc: Gcc Patch List, Manuel López-Ibáñez

Dear Philip,

Another thing to pay attention to is the move to Sphinx for documentation:
https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html

Best,

Manuel.

On Wed, 10 Aug 2022 at 20:57, Philip Herron <philip.herron@embecosm.com>
wrote:

> Hi everyone
>
> For my v2 of the patches, I've been spending a lot of time ensuring
> each patch is buildable. It would end up being simpler if it was
> possible if each patch did not have to be like this so I could split
> up the front-end in more patches. Does this make sense? In theory,
> when everything goes well, does this still mean that we can merge in
> one commit, or should it follow a series of buildable patches? I've
> received feedback that it might be possible to ignore making each
> patch an independent chunk and just focus on splitting it up as small
> as possible even if they don't build.
>
> I hope this makes sense.
>
> Thanks
>
> --Phil
>
> On Thu, 28 Jul 2022 at 10:39, Philip Herron <philip.herron@embecosm.com>
> wrote:
> >
> > Thanks, for confirming David. I think it was too big in the end. I was
> > trying to figure out how to actually split that up but it seems
> > reasonable that I can split up the front-end patches into patches for
> > each separate pass in the compiler seems like a reasonable approach
> > for now.
> >
> > --Phil
> >
> > On Wed, 27 Jul 2022 at 17:45, David Malcolm <dmalcolm@redhat.com> wrote:
> > >
> > > On Wed, 2022-07-27 at 14:40 +0100, herron.philip--- via Gcc-patches
> > > wrote:
> > > > This is the initial version 1 patch set for the Rust front-end. There
> > > > are more changes that need to be extracted out for all the target
> > > > hooks we have implemented. The goal is to see if we are implementing
> > > > the target hooks information for x86 and arm. We have more patches
> > > > for the other targets I can add in here but they all follow the
> > > > pattern established here.
> > > >
> > > > Each patch is buildable on its own and rebased ontop of
> > > > 718cf8d0bd32689192200d2156722167fd21a647. As for ensuring we keep
> > > > attribution for all the patches we have received in the front-end
> > > > should we create a CONTRIBUTOR's file inside the front-end folder?
> > > >
> > > > Note thanks to Thomas Schwinge and Mark Wielaard, we are keeping a
> > > > branch up to date with our code on:
> > > >
> https://gcc.gnu.org/git/?p=gcc.git;a=shortlog;h=refs/heads/devel/rust/master
> > > >  but this is not rebased ontop of gcc head.
> > > >
> > > > Let me know if I have sent these patches correctly or not, this is a
> > > > learning experience with git send-email.
> > > >
> > > > [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder
> > > > [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and
> > > > [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM
> > > > [PATCH Rust front-end v1 4/4] Add Rust front-end and associated
> > >
> > > FWIW it looks like patch 4 of the kit didn't make it (I didn't get a
> > > copy and I don't see it in the archives).
> > >
> > > Maybe it exceeded a size limit?  If so, maybe try splitting it up into
> > > more patches.
> > >
> > > Dave
> > >
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-15 14:07       ` Manuel López-Ibáñez
@ 2022-08-15 14:33         ` Martin Liška
  2022-08-24 13:48           ` Martin Liška
  0 siblings, 1 reply; 20+ messages in thread
From: Martin Liška @ 2022-08-15 14:33 UTC (permalink / raw)
  To: Manuel López-Ibáñez, Philip Herron
  Cc: Gcc Patch List, Manuel López-Ibáñez

On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
> Dear Philip,
> 
> Another thing to pay attention to is the move to Sphinx for documentation:
> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html

Hi.

Which is something I can help you with. I have a script that converts a texinfo documentation
to Sphinx.

Cheers,
Martin

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-15 14:33         ` Martin Liška
@ 2022-08-24 13:48           ` Martin Liška
  2022-08-24 13:51             ` Philip Herron
  0 siblings, 1 reply; 20+ messages in thread
From: Martin Liška @ 2022-08-24 13:48 UTC (permalink / raw)
  To: Manuel López-Ibáñez, Philip Herron
  Cc: Gcc Patch List, Manuel López-Ibáñez

On 8/15/22 16:33, Martin Liška wrote:
> On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
>> Dear Philip,
>>
>> Another thing to pay attention to is the move to Sphinx for documentation:
>> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
> 
> Hi.
> 
> Which is something I can help you with. I have a script that converts a texinfo documentation
> to Sphinx.

@Herron: Do you have any significant documentation changes in the rust branch right now?
I can't see any.

Thanks,
Martin

> 
> Cheers,
> Martin


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-24 13:48           ` Martin Liška
@ 2022-08-24 13:51             ` Philip Herron
  2022-08-24 14:02               ` Martin Liška
  0 siblings, 1 reply; 20+ messages in thread
From: Philip Herron @ 2022-08-24 13:51 UTC (permalink / raw)
  To: Martin Liška
  Cc: Manuel López-Ibáñez, Gcc Patch List,
	Manuel López-Ibáñez

Hi Martin,

Not right now, it is on the to-do list, but do we have to do it in texinfo?

Thanks

--Phil

On Wed, 24 Aug 2022 at 14:49, Martin Liška <mliska@suse.cz> wrote:
>
> On 8/15/22 16:33, Martin Liška wrote:
> > On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
> >> Dear Philip,
> >>
> >> Another thing to pay attention to is the move to Sphinx for documentation:
> >> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
> >
> > Hi.
> >
> > Which is something I can help you with. I have a script that converts a texinfo documentation
> > to Sphinx.
>
> @Herron: Do you have any significant documentation changes in the rust branch right now?
> I can't see any.
>
> Thanks,
> Martin
>
> >
> > Cheers,
> > Martin
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: Rust frontend patches v1
  2022-08-24 13:51             ` Philip Herron
@ 2022-08-24 14:02               ` Martin Liška
  0 siblings, 0 replies; 20+ messages in thread
From: Martin Liška @ 2022-08-24 14:02 UTC (permalink / raw)
  To: Philip Herron
  Cc: Manuel López-Ibáñez, Gcc Patch List,
	Manuel López-Ibáñez

On 8/24/22 15:51, Philip Herron wrote:
> Hi Martin,
> 
> Not right now, it is on the to-do list, but do we have to do it in texinfo?

Well, I still hope we will move to Sphinx (and remove Texinfo) after the Cauldron.
Anyway, using Sphinx is even now possible as a default documentation formal (see libgccjit,
Ada manuals), where one exports Sphinx to texinfo.

Cheers,
Martin

> 
> Thanks
> 
> --Phil
> 
> On Wed, 24 Aug 2022 at 14:49, Martin Liška <mliska@suse.cz> wrote:
>>
>> On 8/15/22 16:33, Martin Liška wrote:
>>> On 8/15/22 16:07, Manuel López-Ibáñez via Gcc-patches wrote:
>>>> Dear Philip,
>>>>
>>>> Another thing to pay attention to is the move to Sphinx for documentation:
>>>> https://gcc.gnu.org/pipermail/gcc/2022-August/239233.html
>>>
>>> Hi.
>>>
>>> Which is something I can help you with. I have a script that converts a texinfo documentation
>>> to Sphinx.
>>
>> @Herron: Do you have any significant documentation changes in the rust branch right now?
>> I can't see any.
>>
>> Thanks,
>> Martin
>>
>>>
>>> Cheers,
>>> Martin
>>


^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2022-08-24 14:02 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-27 13:40 Rust frontend patches v1 herron.philip
2022-07-27 13:40 ` [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder herron.philip
2022-07-27 13:40 ` [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 herron.philip
2022-07-28  9:57   ` Jakub Jelinek
2022-07-28 10:38   ` Thomas Schwinge
2022-07-28 10:51     ` Philip Herron
2022-07-28 11:08       ` Thomas Schwinge
2022-07-28 11:41         ` Philip Herron
2022-07-27 13:40 ` [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM herron.philip
2022-07-27 14:13   ` Richard Earnshaw
2022-07-27 16:45 ` Rust frontend patches v1 David Malcolm
2022-07-28  9:39   ` Philip Herron
2022-08-10 18:56     ` Philip Herron
2022-08-10 19:06       ` David Malcolm
2022-08-12 20:45       ` Mike Stump
2022-08-15 14:07       ` Manuel López-Ibáñez
2022-08-15 14:33         ` Martin Liška
2022-08-24 13:48           ` Martin Liška
2022-08-24 13:51             ` Philip Herron
2022-08-24 14:02               ` Martin Liška

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).