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: 254 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:b5d6:b0:2b9:3548:2db5 with SMTP id v22csp414457pxt; Wed, 27 Jul 2022 06:42:23 -0700 (PDT) X-Google-Smtp-Source: AGRyM1swWqkTAnvlYb/CN+PuYDL9e1pCcbcITEAoWQYgXAiGEW/vEPUirftaTaLCi5PnP+j8RZPV X-Received: by 2002:a17:907:2cf2:b0:72b:4a01:e8bb with SMTP id hz18-20020a1709072cf200b0072b4a01e8bbmr18032598ejc.673.1658929343101; Wed, 27 Jul 2022 06:42:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658929343; cv=none; d=google.com; s=arc-20160816; b=IH9HYg7wolWoSjEKOc8f1QSUg0gJRuT/mRGLf9Z3eu4wx1Txhjj/1otci/gGi+GYit bKaFEv0F9jK87HMjzGuFNZeaYtBzAkhCBq35a1upVSU1Y4XXFUxDCWEJlGOqAKCipl5F vGISUe6VJ/IcnG0tssrGWpOdxsbzucONedNi9unYh/jJY/xXIYBnYtRZce0RKxM9N/TJ tyQUuVnpoPrCFhp9ybp6tmDT+Jv4gjrC8ezIWrnJx7byuYlJ9bktQBF3OcXJkZDucsv5 LUn1v8Um0fKJLd82o0UFfXxY9kJuzNKFPHbPfKsENtIcJACXY9hwPRkQA3yf8xh5GBfh XU7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=kMd72iurV/p434H7M8RFO/HaN3fyWyZT1F7HgqktUcQ=; b=u2/cLZraJxKv6wnRFmyG7bb2XiehmB6YiHbEVMi3d++PohU8oXMv2bos8nv1kfP0tH trP9BcH4QKpgjYqWNz6+13oEzUfHu3GTA1O1MuWYbKemIuLRIB/OqEpJkryeFHf0m6FG Jcje/PU+LDbj5919G6d7snvpqgzuixg9JesdtrJ8xCSSoFIhxaTV6/a4McpTvb13lrHo 8Ye2xZcqtNAxURQUxwWSpBrQySQS1/3PRHwVUAHyeQTv1bjwgWYQsqDBx7Qb3Q6CYwX9 ori22Rr/u9J5IjOLornQiGvkxF0vW2D7sYpMkOEixAEaBmv/+E0Sa7pYEnutrW4TJMZo GqDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=S3ehp35m; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id pk9-20020a170906d7a900b0072afabeabbbsi15568459ejb.47.2022.07.27.06.42.22 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 27 Jul 2022 06:42:23 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=S3ehp35m; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DEE66385695B for ; Wed, 27 Jul 2022 13:41:48 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DEE66385695B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1658929308; 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=S3ehp35mM1pR9RrKdaOE8tQkx9VOCBzFxY5BrnfK4X1LruAd09WReXgZLzmK+P68X Vhlioo+33QUq7Fnhcc/uFNATuPvHftjYKWfC43cLrpBjxMdDI2XefvibHerOSYoiPO C9k1avVu+v+0mqDnhn7eN0HgGbDm2A4dU+9eRK5g= 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-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+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1739513495011586577?= X-GMAIL-MSGID: =?utf-8?q?1739513495011586577?= 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