From patchwork Wed Jul 27 13:40:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 56369 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E67FD385BACC for ; Wed, 27 Jul 2022 13:41:31 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E67FD385BACC DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658929291; bh=Ecb9TYxFQ2VynrxSbH+uZ2AovHd84J1IaRhOMEJqqmk=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=MRcFDaK2/FDmg67H6ggjvBQZdQo4UIvC08p1WOEMb8HAiF5pBdvbbAMBXEF3AUfuI 3tNolwvPCmXTSeVSsCHpLx8ZYffpNjMUNg7sDgbWwnnj8iHs192vJX3PuqFFElBFx+ B3vupylE4NaS4dwqWxe9o38GuH41RZu2uekpDVgU= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42c.google.com (mail-wr1-x42c.google.com [IPv6:2a00:1450:4864:20::42c]) by sourceware.org (Postfix) with ESMTPS id 5D1893857001 for ; Wed, 27 Jul 2022 13:40:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 5D1893857001 Received: by mail-wr1-x42c.google.com with SMTP id l22so2693788wrz.7 for ; Wed, 27 Jul 2022 06:40:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=Ecb9TYxFQ2VynrxSbH+uZ2AovHd84J1IaRhOMEJqqmk=; b=TCdjGoPbNR1miLaojJNwCcZ5q23sVKj0WYf1TfxTntRNGKEa0PbaLcm2hdmoAJjOLP JVcGfL/mxzKgqK2dcO9Ta7a4K8q7Sfe2NqJ5FZg9d2eLEEmt9SGPYHr3EvTkXwJiMFYd 0MlzktmQOfvaQpadzG4LGNcBnV6PjfcGUg+6Nl16YKbLEgPmJ41VXyB7ZMEAXGF7IbVO tB46rYOBKGww+pJSuP0SR8+JyXLBVHm3wc4PXuSgxavsvid0qAVsZm9Ij5BAITX3gc/j e8ENzbmOO/t0lYURvc/FK7Ml1IgCocQyzcRoP5rWki1Vksve90MJptM+9Qpi0znFs+mW HBjQ== X-Gm-Message-State: AJIora/BM6qVGRT4/UZfmyhqtdrw2lYU/F9e539jc30Jdgnd0feJfEkY mySGTRBk0WcDqvE2O6q4dxYXd7IduDinQQ== X-Google-Smtp-Source: AGRyM1sfKCtr2QS4/8UelSX9AVIAlstuGNIrDIVb2ytgLkH9onr2XXmnKe4auoYlJVvj8omnRpqMKQ== X-Received: by 2002:a5d:64ad:0:b0:21e:576c:db1f with SMTP id m13-20020a5d64ad000000b0021e576cdb1fmr14538169wrp.75.1658929255236; Wed, 27 Jul 2022 06:40:55 -0700 (PDT) Received: from localhost.localdomain ([86.14.124.218]) by smtp.gmail.com with ESMTPSA id u18-20020a5d4352000000b0021e297d6850sm16846195wrr.110.2022.07.27.06.40.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Jul 2022 06:40:54 -0700 (PDT) X-Google-Original-From: philip.herron@embecosm.com To: gcc-patches@gcc.gnu.org Subject: [PATCH Rust front-end v1 1/4] Add skeleton Rust front-end folder Date: Wed, 27 Jul 2022 14:40:37 +0100 Message-Id: <20220727134040.843750-2-philip.herron@embecosm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220727134040.843750-1-philip.herron@embecosm.com> References: <20220727134040.843750-1-philip.herron@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-10.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "herron.philip--- via Gcc-patches" From: "Li, Pan2 via Gcc-patches" Reply-To: philip.herron@embecosm.com Cc: herron.philip@googlemail.com, Philip Herron Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Philip Herron 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 +# . + +# 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 +# . + +# 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 + . */ + +/* 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 +; . + +; 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 +// . + +#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 + +// 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 /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 +. */ + +#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. */ From patchwork Wed Jul 27 13:40:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 56371 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4D5E1385C302 for ; Wed, 27 Jul 2022 13:42:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4D5E1385C302 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658929357; bh=2D/Hay8pJOcpDxfGYzdeghmiAQ6f0nQ2+qYlFcn7yvY=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=w73Kroh0diuiWGUE2nH7oeS333zl63ml4e3zIrnkfpL1Kwp8vGP8KOw0f3G/FGzue 4BiVqfM+DAIaW8m4vCXtYo/XUSR/3r4vhsD+NbPjykjR1ean/CXgxYsPElfxrcAqVU mwxvk7Un6wBu7hhCsHhUtBBndNXkndMJY+iMgQZk= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42b.google.com (mail-wr1-x42b.google.com [IPv6:2a00:1450:4864:20::42b]) by sourceware.org (Postfix) with ESMTPS id A43CA385AC2F for ; Wed, 27 Jul 2022 13:40:59 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A43CA385AC2F Received: by mail-wr1-x42b.google.com with SMTP id d8so24154946wrp.6 for ; Wed, 27 Jul 2022 06:40:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=2D/Hay8pJOcpDxfGYzdeghmiAQ6f0nQ2+qYlFcn7yvY=; b=rFHeIy+xfzLVfNN1lYHL+SpgwxfPTTeoivWZWLeFK4fM8hS4uT2s52rBKeqt6oT9kK Anb4lOru1VmzG3m7G4VT5elkYKWseIOG87yNWoZAtsjqbPU0z84yqG2QMv7XorMYFG60 meyk4kl0e18K7u8X0fPWZ/hznB2XuJLGdryqlqxQ1yQFjVqxMq6dRCuICHiOIytRMY6+ La0yNR9Wg+DsmV2TSJC0ka+MPirCpSFClz07F2hY84cHr57m8u6QnV0OEQprXzXh68hY TrJnkdnJvxN30Ig56bHcXiTzg/1gX79If/f6CyPA5NscNEdxGqZ03xx8d+ZxHO3n2QMj hooQ== X-Gm-Message-State: AJIora8BSefaGLSFWvWsv7zeeb+euaRYbR7r/TpR2GlCGoOKPOMWFOuS EZp60CuBeQbO2yBl9hdLIWUVxBWolcsKzA== X-Google-Smtp-Source: AGRyM1tEfJ1BYyEtHNPtFACIlIaTN7KktfFMUHUDplw6BFfQV4TrjkrTGSEuH56v0+A0XvsXYPo5Vg== X-Received: by 2002:adf:fb0e:0:b0:21a:34a2:5ca9 with SMTP id c14-20020adffb0e000000b0021a34a25ca9mr14531755wrr.472.1658929257036; Wed, 27 Jul 2022 06:40:57 -0700 (PDT) Received: from localhost.localdomain ([86.14.124.218]) by smtp.gmail.com with ESMTPSA id u18-20020a5d4352000000b0021e297d6850sm16846195wrr.110.2022.07.27.06.40.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Jul 2022 06:40:55 -0700 (PDT) X-Google-Original-From: philip.herron@embecosm.com To: gcc-patches@gcc.gnu.org Subject: [PATCH Rust front-end v1 2/4] Add Rust lang TargetHooks for i386 and x86_64 Date: Wed, 27 Jul 2022 14:40:38 +0100 Message-Id: <20220727134040.843750-3-philip.herron@embecosm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220727134040.843750-1-philip.herron@embecosm.com> References: <20220727134040.843750-1-philip.herron@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_NUMSUBJECT, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "herron.philip--- via Gcc-patches" From: "Li, Pan2 via Gcc-patches" Reply-To: philip.herron@embecosm.com Cc: herron.philip@googlemail.com, SimplyTheOther , Philip Herron Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Philip Herron 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 --- 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 # 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 +. */ + +#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 . 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 +. */ + +#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 + . */ + +#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 + . */ + +/* 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 + . */ + +#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 From patchwork Wed Jul 27 13:40:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Pan2 via Gcc-patches" X-Patchwork-Id: 56370 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 99D383856DD1 for ; Wed, 27 Jul 2022 13:41:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 99D383856DD1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658929293; bh=kMd72iurV/p434H7M8RFO/HaN3fyWyZT1F7HgqktUcQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=puqT3Oyuos3mgAWJL1LhnRtgSIBnr5Kv1NbK6kq74ppiEjLQYqh2BQcXoLRt6iEoM pAKY19XUPMVflZIwXhZyDOzr27DxvEQ8jcNZRSenyj5wmqvFfhYoi0NhN8jBrFMeog aj7DVzGrSeJIjKudziJhHuYCp0nKOUi3FKQWsqsc= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-wr1-x42f.google.com (mail-wr1-x42f.google.com [IPv6:2a00:1450:4864:20::42f]) by sourceware.org (Postfix) with ESMTPS id A03063857030 for ; Wed, 27 Jul 2022 13:41:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A03063857030 Received: by mail-wr1-x42f.google.com with SMTP id j7so2345551wrh.3 for ; Wed, 27 Jul 2022 06:41:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:reply-to:mime-version:content-transfer-encoding; bh=kMd72iurV/p434H7M8RFO/HaN3fyWyZT1F7HgqktUcQ=; b=t3acJ883pBVZMC9tkpoJBRHof2EBNnOnHsUXvU7xKJnihAVfsa8rBse3IlHntLjXo9 X85Na+Hg8yeeI20vpWVpzSZzG9ZyPQrJMRVjZp4CFUFNF594zsbUknplJoqcSgupLZgP 7Wrh8/E/qSoBebu0CEux+dM8B50ZcbmgDe1JlvQjoLFeywheKz1kVmBDk3vtoBPhmlyS DjQ7q9QrI3SSr1iEChWMZtTo2ZXGLQajPTxLJNl/9LmbX85CqnIuyLvLK3uSntVdj4MX 5TD0IoeLRbyVUrlA9fNOXztI4nh6srFic21z+1w1svnu77c2bS5bk9OVT7f3sBSSRotY joQg== X-Gm-Message-State: AJIora/Qkf0dHwBwuyhdYspFN1PcR748mInLGwXfekF0cLFV+GH+NRVr 1WaN21MzT9kmg+aFGonVXRwneCnV+kDj0g== X-Google-Smtp-Source: AGRyM1u//MTe618zS1rfSlqAw49cEDktM3fL5VGaDM66QAW4UBQUSIWyZpU5XAdaE6UAGtULTgG8jw== X-Received: by 2002:a5d:64c1:0:b0:21d:ac34:d086 with SMTP id f1-20020a5d64c1000000b0021dac34d086mr13965680wri.319.1658929258714; Wed, 27 Jul 2022 06:40:58 -0700 (PDT) Received: from localhost.localdomain ([86.14.124.218]) by smtp.gmail.com with ESMTPSA id u18-20020a5d4352000000b0021e297d6850sm16846195wrr.110.2022.07.27.06.40.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Jul 2022 06:40:57 -0700 (PDT) X-Google-Original-From: philip.herron@embecosm.com To: gcc-patches@gcc.gnu.org Subject: [PATCH Rust front-end v1 3/4] Add Rust target hooks to ARM Date: Wed, 27 Jul 2022 14:40:39 +0100 Message-Id: <20220727134040.843750-4-philip.herron@embecosm.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220727134040.843750-1-philip.herron@embecosm.com> References: <20220727134040.843750-1-philip.herron@embecosm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "herron.philip--- via Gcc-patches" From: "Li, Pan2 via Gcc-patches" Reply-To: philip.herron@embecosm.com Cc: herron.philip@googlemail.com, SimplyTheOther , Philip Herron Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" From: Philip Herron 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 --- 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 +. */ + +#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