From patchwork Fri Feb 10 19:38:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Brodkin X-Patchwork-Id: 752859 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w83690JFRz9s4s for ; Fri, 21 Apr 2017 01:42:41 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="sYmfODBA"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Subject:References: In-Reply-To:Message-Id:Date:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=9ZxWGZV+pHMPuOlVtOp3kiDwn1rQm83AgmNNPfmFZGs=; b=sYmfODBA/NRjDT WJ+CFA4P8LHi0ArITrF+Bx7kh7mJ7QAQaBRQYXubEBDSadysVpekByEZB9CKvfZt2TbmH9uMl7qBP nnX8T9DejJpGUQmgr7z0Cqw2DqotjV4RebkZT0viraqteZX3gy7+ZXAwhm34Nl0kxym2qE3tvJluV sJco+3uxxlWFsJMgSOvySMssMP0fovsYhfUKna7uqOfcPsvck+niN5VzlVLAIpMhIr30IHxtozOQC 0r/M4WLeGJDBanqujdlsC6Cwz/bFyAWRW2G4lTZ+lRQM/jz4z8cMdjG4hTWPw4g2M3rSTeXs5SC4P ZRd/mF3XsJ1r7Ivh524g==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1d1EE3-0002vO-VX; Thu, 20 Apr 2017 15:42:32 +0000 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9] helo=smtprelay.synopsys.com) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1ccH1u-0007zN-Q3 for lede-dev@lists.infradead.org; Fri, 10 Feb 2017 19:40:57 +0000 Received: from mailhost.synopsys.com (mailhost2.synopsys.com [10.13.184.66]) by smtprelay.synopsys.com (Postfix) with ESMTP id 9C0FD24E1394; Fri, 10 Feb 2017 11:38:28 -0800 (PST) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id C68A82F2; Fri, 10 Feb 2017 11:38:27 -0800 (PST) Received: from ru20arcgnu1.internal.synopsys.com (ru20arcgnu1.internal.synopsys.com [10.121.9.48]) by mailhost.synopsys.com (Postfix) with ESMTP id 4F678254; Fri, 10 Feb 2017 11:38:23 -0800 (PST) From: Alexey Brodkin To: lede-dev@lists.infradead.org Date: Fri, 10 Feb 2017 22:38:08 +0300 Message-Id: <20170210193810.8573-4-Alexey.Brodkin@synopsys.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170210193810.8573-1-Alexey.Brodkin@synopsys.com> References: <20170210193810.8573-1-Alexey.Brodkin@synopsys.com> X-Spam-Note: CRM114 run bypassed due to message size (807266 bytes) X-Spam-Note: SpamAssassin invocation failed X-Mailman-Approved-At: Thu, 20 Apr 2017 08:42:29 -0700 Subject: [LEDE-DEV] [RFC 3/5] toolchain: gcc: Add all patches from arc-2017.03 branch X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Felix Fietkau , Alexey Brodkin , John Crispin MIME-Version: 1.0 Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The most recent release of GCC misses quite a lot of patches we need for ARC. Some are fixes, some improvements but most of them are already in GCC's master branch and will be a part of GCC v7.0. Signed-off-by: Alexey Brodkin --- .../0001-ARC-Add-SIMD-extensions-for-ARC-HS.patch | 905 ++++++++ .../6.3.0/0002-ARC-LIBGCC-Add-TLS-support.patch | 144 ++ .../patches/6.3.0/0003-ARC-Add-TLS-support.patch | 1147 ++++++++++ ...se-drsub-instructions-when-selecting-fpud.patch | 121 ++ ...-FPUDA-code-gen-when-compiling-for-big-en.patch | 140 ++ .../6.3.0/0006-ARC-Pass-mfpuda-to-assembler.patch | 46 + ...Andrew-Burgess-andrew.burgess-embecosm.co.patch | 128 ++ ...Andrew-Burgess-andrew.burgess-embecosm.co.patch | 78 + ...Joern-Rennecke-joern.rennecke-embecosm.co.patch | 701 +++++++ ...Joern-Rennecke-joern.rennecke-embecosm.co.patch | 1059 ++++++++++ ...Joern-Rennecke-joern.rennecke-embecosm.co.patch | 116 ++ ...Andrew-Burgess-andrew.burgess-embecosm.co.patch | 59 + ...anted-match-for-sign-extend-16-bit-consta.patch | 170 ++ .../6.3.0/0014-ARC-Fix-obsolete-constraint.patch | 72 + ...FPX-NaN-within-optimized-floating-point-l.patch | 133 ++ ...Andrew-Burgess-andrew.burgess-embecosm.co.patch | 123 ++ .../0017-ARC-Add-new-ARCv2-instructions.patch | 785 +++++++ .../0018-Fix-warnings-update-source-code.patch | 80 + ...019-ARC-Various-instruction-pattern-fixes.patch | 83 + .../6.3.0/0020-ARC-New-CPU-C-define-handler.patch | 303 +++ ...OFFPC-relocation-for-pc-relative-accesses.patch | 197 ++ ...ption-handling-refurbish-multilib-support.patch | 2188 ++++++++++++++++++++ ...023-ARC-Various-small-miscellaneous-fixes.patch | 243 +++ ...Disable-compact-casesi-patterns-for-arcv2.patch | 50 + ...025-ARC-Add-support-for-QuarkSE-processor.patch | 429 ++++ ...-libgcc-Add-support-for-QuarkSE-processor.patch | 441 ++++ .../6.3.0/0027-ARC-libgcc-Fix-defines.patch | 198 ++ ...28-ARC-tests-Update-target-specific-tests.patch | 1103 ++++++++++ .../gcc/patches/6.3.0/0029-ARC-Various-fixes.patch | 84 + .../0030-ARC-Add-simple-shift-rotate-ops.patch | 68 + .../gcc/patches/6.3.0/0031-Fix-option-text.patch | 44 + .../0032-ARC-Disable-tests-for-bare-metal.patch | 133 ++ .../0033-ARC-Update-INSN_LENGTH_ALIGNMENT.patch | 34 + ...RC-Reimplement-exception-handling-support.patch | 523 +++++ .../6.3.0/0035-ARC-Fix-mul32x16-patterns.patch | 56 + .../6.3.0/0036-ARC-Cleanup-implementation.patch | 201 ++ .../6.3.0/0037-ARC-Refurbish-mul64-support.patch | 126 ++ toolchain/gcc/patches/6.3.0/0038-ARC-Fix-PIE.patch | 100 + .../0039-ARC-Generating-code-for-profiling.patch | 2136 +++++++++++++++++++ .../6.3.0/0040-ARC-Clean-up-arc-header-file.patch | 501 +++++ ...re-script-to-allow-non-uclibc-based-tripl.patch | 49 + ...0042-ARC-Fix-conditional-move-contstraint.patch | 32 + .../6.3.0/0043-Fix-tst_bitfield_tst-pattern.patch | 66 + .../0044-ARC-Prohibit-negative-PIC-constants.patch | 105 + ...0045-ARC-Handle-complex-PIC-move-patterns.patch | 120 ++ .../0046-ARC-Add-code-density-instructions.patch | 300 +++ .../6.3.0/0047-ARC-Code-size-modifications.patch | 107 + .../0048-ARC-Save-restore-blink-when-in-ISR.patch | 90 + ...ection-of-long-immediate-for-load-store-o.patch | 51 + ...-TP-register-when-building-for-bare-metal.patch | 58 + .../0051-ARC-Fix-divdf3-emulation-for-arcem.patch | 53 + ...ic-context-save-restore-for-regular-inter.patch | 721 +++++++ .../6.3.0/0053-ARC-Fast-interrupts-support.patch | 575 +++++ .../0054-ARC-Add-support-for-QuarkSE2-EM-cpu.patch | 269 +++ ...ARC-Fix-move_double_src_operand-predicate.patch | 37 + .../6.3.0/0056-ARC-Remove-old-prof-patterns.patch | 107 + ...-ARC-Update-mode_dependent_address_p-hook.patch | 40 + ...058-Changed-tests-to-verify-shared-option.patch | 56 + .../6.3.0/0059-ARC-DWARF-emitting-cleanup.patch | 75 + .../0060-ARC-Use-long-jumps-for-CRT-calls.patch | 36 + .../6.3.0/0061-ARC-Fix-typo-in-arc.opt.patch | 35 + ...fine-SIZE_TYPE-and-PTRDIFF_TYPE-correctly.patch | 38 + ...CK-Hard-check-for-the-LP-size-constraints.patch | 38 + .../patches/6.3.0/0064-ARC-Fix-sub_n-pattern.patch | 29 + ...C-Make-mulsi-for-A700-pattern-commutative.patch | 29 + .../0066-ARC-Fix-LE-tests-for-nps400-variant.patch | 125 ++ ...0067-ARC-Make-lp_count-reg-fix-for-ARC600.patch | 53 + ...support-for-advanced-mpy-mac-instructions.patch | 376 ++++ .../6.3.0/0069-ARC-Fix-typo-dmpyh-pattern.patch | 29 + ...ntiate-between-ARCv1-and-ARCv2-h-reg-clas.patch | 120 ++ ...ntiate-between-ARCv1-and-ARCv2-h-reg-clas.patch | 89 + ...xtension-core-registers-to-be-used-for-ad.patch | 60 + ...-Make-D0-D1-double-regs-fix-when-not-used.patch | 33 + ...L-ACCH-registers-whenever-they-are-availa.patch | 36 + ...id-use-of-hard-registers-before-reg-alloc.patch | 236 +++ ...ARC-Allow-r30-to-be-used-by-the-reg-alloc.patch | 52 + ...ARC-Cxx-Fix-calling-multiple-inheritances.patch | 55 + ...resses-can-use-long-immediate-for-offsets.patch | 94 + .../0079-ARC-Add-support-for-naked-functions.patch | 512 +++++ ...rect-and-update-ARC-builtin-documentation.patch | 204 ++ ...predicate-movv2hi-to-avoid-scaled-address.patch | 30 + ...non-commutative_binary_comparison-pattern.patch | 63 + ...-moving-stores-to-the-frame-before-the-st.patch | 86 + .../0084-ARC-LRA-Fix-tests-asm-constraints.patch | 46 + ...ainst-frame_pointer_needed-in-arc_can_eli.patch | 35 + ...0086-ARC-Define-ADDITIONAL_REGISTER_NAMES.patch | 36 + ...RA-Avoid-emitting-COND_EXEC-during-expand.patch | 101 + .../0088-ARC-Clean-up-building-warnings.patch | 154 ++ ...ribute-naked-do-not-emit-return-instructi.patch | 64 + 89 files changed, 21053 insertions(+) create mode 100644 toolchain/gcc/patches/6.3.0/0001-ARC-Add-SIMD-extensions-for-ARC-HS.patch create mode 100644 toolchain/gcc/patches/6.3.0/0002-ARC-LIBGCC-Add-TLS-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0003-ARC-Add-TLS-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0004-ARC-Don-t-use-drsub-instructions-when-selecting-fpud.patch create mode 100644 toolchain/gcc/patches/6.3.0/0005-ARC-Fix-FPX-FPUDA-code-gen-when-compiling-for-big-en.patch create mode 100644 toolchain/gcc/patches/6.3.0/0006-ARC-Pass-mfpuda-to-assembler.patch create mode 100644 toolchain/gcc/patches/6.3.0/0007-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0008-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0009-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0010-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0011-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0012-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0013-ARC-Fix-unwanted-match-for-sign-extend-16-bit-consta.patch create mode 100644 toolchain/gcc/patches/6.3.0/0014-ARC-Fix-obsolete-constraint.patch create mode 100644 toolchain/gcc/patches/6.3.0/0015-ARC-Handle-FPX-NaN-within-optimized-floating-point-l.patch create mode 100644 toolchain/gcc/patches/6.3.0/0016-2016-04-29-Andrew-Burgess-andrew.burgess-embecosm.co.patch create mode 100644 toolchain/gcc/patches/6.3.0/0017-ARC-Add-new-ARCv2-instructions.patch create mode 100644 toolchain/gcc/patches/6.3.0/0018-Fix-warnings-update-source-code.patch create mode 100644 toolchain/gcc/patches/6.3.0/0019-ARC-Various-instruction-pattern-fixes.patch create mode 100644 toolchain/gcc/patches/6.3.0/0020-ARC-New-CPU-C-define-handler.patch create mode 100644 toolchain/gcc/patches/6.3.0/0021-Use-GOTOFFPC-relocation-for-pc-relative-accesses.patch create mode 100644 toolchain/gcc/patches/6.3.0/0022-ARC-New-option-handling-refurbish-multilib-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0023-ARC-Various-small-miscellaneous-fixes.patch create mode 100644 toolchain/gcc/patches/6.3.0/0024-ARC-Disable-compact-casesi-patterns-for-arcv2.patch create mode 100644 toolchain/gcc/patches/6.3.0/0025-ARC-Add-support-for-QuarkSE-processor.patch create mode 100644 toolchain/gcc/patches/6.3.0/0026-ARC-libgcc-Add-support-for-QuarkSE-processor.patch create mode 100644 toolchain/gcc/patches/6.3.0/0027-ARC-libgcc-Fix-defines.patch create mode 100644 toolchain/gcc/patches/6.3.0/0028-ARC-tests-Update-target-specific-tests.patch create mode 100644 toolchain/gcc/patches/6.3.0/0029-ARC-Various-fixes.patch create mode 100644 toolchain/gcc/patches/6.3.0/0030-ARC-Add-simple-shift-rotate-ops.patch create mode 100644 toolchain/gcc/patches/6.3.0/0031-Fix-option-text.patch create mode 100644 toolchain/gcc/patches/6.3.0/0032-ARC-Disable-tests-for-bare-metal.patch create mode 100644 toolchain/gcc/patches/6.3.0/0033-ARC-Update-INSN_LENGTH_ALIGNMENT.patch create mode 100644 toolchain/gcc/patches/6.3.0/0034-ARC-Reimplement-exception-handling-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0035-ARC-Fix-mul32x16-patterns.patch create mode 100644 toolchain/gcc/patches/6.3.0/0036-ARC-Cleanup-implementation.patch create mode 100644 toolchain/gcc/patches/6.3.0/0037-ARC-Refurbish-mul64-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0038-ARC-Fix-PIE.patch create mode 100644 toolchain/gcc/patches/6.3.0/0039-ARC-Generating-code-for-profiling.patch create mode 100644 toolchain/gcc/patches/6.3.0/0040-ARC-Clean-up-arc-header-file.patch create mode 100644 toolchain/gcc/patches/6.3.0/0041-ARC-Configure-script-to-allow-non-uclibc-based-tripl.patch create mode 100644 toolchain/gcc/patches/6.3.0/0042-ARC-Fix-conditional-move-contstraint.patch create mode 100644 toolchain/gcc/patches/6.3.0/0043-Fix-tst_bitfield_tst-pattern.patch create mode 100644 toolchain/gcc/patches/6.3.0/0044-ARC-Prohibit-negative-PIC-constants.patch create mode 100644 toolchain/gcc/patches/6.3.0/0045-ARC-Handle-complex-PIC-move-patterns.patch create mode 100644 toolchain/gcc/patches/6.3.0/0046-ARC-Add-code-density-instructions.patch create mode 100644 toolchain/gcc/patches/6.3.0/0047-ARC-Code-size-modifications.patch create mode 100644 toolchain/gcc/patches/6.3.0/0048-ARC-Save-restore-blink-when-in-ISR.patch create mode 100644 toolchain/gcc/patches/6.3.0/0049-ARC-Fix-detection-of-long-immediate-for-load-store-o.patch create mode 100644 toolchain/gcc/patches/6.3.0/0050-ARC-Disable-TP-register-when-building-for-bare-metal.patch create mode 100644 toolchain/gcc/patches/6.3.0/0051-ARC-Fix-divdf3-emulation-for-arcem.patch create mode 100644 toolchain/gcc/patches/6.3.0/0052-ARC-Automatic-context-save-restore-for-regular-inter.patch create mode 100644 toolchain/gcc/patches/6.3.0/0053-ARC-Fast-interrupts-support.patch create mode 100644 toolchain/gcc/patches/6.3.0/0054-ARC-Add-support-for-QuarkSE2-EM-cpu.patch create mode 100644 toolchain/gcc/patches/6.3.0/0055-ARC-Fix-move_double_src_operand-predicate.patch create mode 100644 toolchain/gcc/patches/6.3.0/0056-ARC-Remove-old-prof-patterns.patch create mode 100644 toolchain/gcc/patches/6.3.0/0057-ARC-Update-mode_dependent_address_p-hook.patch create mode 100644 toolchain/gcc/patches/6.3.0/0058-Changed-tests-to-verify-shared-option.patch create mode 100644 toolchain/gcc/patches/6.3.0/0059-ARC-DWARF-emitting-cleanup.patch create mode 100644 toolchain/gcc/patches/6.3.0/0060-ARC-Use-long-jumps-for-CRT-calls.patch create mode 100644 toolchain/gcc/patches/6.3.0/0061-ARC-Fix-typo-in-arc.opt.patch create mode 100644 toolchain/gcc/patches/6.3.0/0062-ARC-define-SIZE_TYPE-and-PTRDIFF_TYPE-correctly.patch create mode 100644 toolchain/gcc/patches/6.3.0/0063-ARC-HACK-Hard-check-for-the-LP-size-constraints.patch create mode 100644 toolchain/gcc/patches/6.3.0/0064-ARC-Fix-sub_n-pattern.patch create mode 100644 toolchain/gcc/patches/6.3.0/0065-ARC-Make-mulsi-for-A700-pattern-commutative.patch create mode 100644 toolchain/gcc/patches/6.3.0/0066-ARC-Fix-LE-tests-for-nps400-variant.patch create mode 100644 toolchain/gcc/patches/6.3.0/0067-ARC-Make-lp_count-reg-fix-for-ARC600.patch create mode 100644 toolchain/gcc/patches/6.3.0/0068-ARC-Add-support-for-advanced-mpy-mac-instructions.patch create mode 100644 toolchain/gcc/patches/6.3.0/0069-ARC-Fix-typo-dmpyh-pattern.patch create mode 100644 toolchain/gcc/patches/6.3.0/0070-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch create mode 100644 toolchain/gcc/patches/6.3.0/0071-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch create mode 100644 toolchain/gcc/patches/6.3.0/0072-ARC-Allow-extension-core-registers-to-be-used-for-ad.patch create mode 100644 toolchain/gcc/patches/6.3.0/0073-ARC-Make-D0-D1-double-regs-fix-when-not-used.patch create mode 100644 toolchain/gcc/patches/6.3.0/0074-ARC-Use-ACCL-ACCH-registers-whenever-they-are-availa.patch create mode 100644 toolchain/gcc/patches/6.3.0/0075-ARC-Avoid-use-of-hard-registers-before-reg-alloc.patch create mode 100644 toolchain/gcc/patches/6.3.0/0076-ARC-Allow-r30-to-be-used-by-the-reg-alloc.patch create mode 100644 toolchain/gcc/patches/6.3.0/0077-ARC-Cxx-Fix-calling-multiple-inheritances.patch create mode 100644 toolchain/gcc/patches/6.3.0/0078-ARC-Addresses-can-use-long-immediate-for-offsets.patch create mode 100644 toolchain/gcc/patches/6.3.0/0079-ARC-Add-support-for-naked-functions.patch create mode 100644 toolchain/gcc/patches/6.3.0/0080-ARC-Correct-and-update-ARC-builtin-documentation.patch create mode 100644 toolchain/gcc/patches/6.3.0/0081-ARC-Change-predicate-movv2hi-to-avoid-scaled-address.patch create mode 100644 toolchain/gcc/patches/6.3.0/0082-ARC-Update-non-commutative_binary_comparison-pattern.patch create mode 100644 toolchain/gcc/patches/6.3.0/0083-ARC-Prevent-moving-stores-to-the-frame-before-the-st.patch create mode 100644 toolchain/gcc/patches/6.3.0/0084-ARC-LRA-Fix-tests-asm-constraints.patch create mode 100644 toolchain/gcc/patches/6.3.0/0085-ARC-Test-against-frame_pointer_needed-in-arc_can_eli.patch create mode 100644 toolchain/gcc/patches/6.3.0/0086-ARC-Define-ADDITIONAL_REGISTER_NAMES.patch create mode 100644 toolchain/gcc/patches/6.3.0/0087-ARC-LRA-Avoid-emitting-COND_EXEC-during-expand.patch create mode 100644 toolchain/gcc/patches/6.3.0/0088-ARC-Clean-up-building-warnings.patch create mode 100644 toolchain/gcc/patches/6.3.0/0089-ARC-FIX-Attribute-naked-do-not-emit-return-instructi.patch diff --git a/toolchain/gcc/patches/6.3.0/0001-ARC-Add-SIMD-extensions-for-ARC-HS.patch b/toolchain/gcc/patches/6.3.0/0001-ARC-Add-SIMD-extensions-for-ARC-HS.patch new file mode 100644 index 0000000..6b28a8d --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0001-ARC-Add-SIMD-extensions-for-ARC-HS.patch @@ -0,0 +1,905 @@ +From d648963475c68b7193f206a79f26fbd61549c9fb Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 09:53:13 +0000 +Subject: [PATCH 01/89] [ARC] Add SIMD extensions for ARC HS + +gcc/ +2016-04-28 Claudiu Zissulescu + + * config/arc/arc.c (arc_vector_mode_supported_p): Add support for + the new ARC HS SIMD instructions. + (arc_preferred_simd_mode): New function. + (arc_autovectorize_vector_sizes): Likewise. + (TARGET_VECTORIZE_PREFERRED_SIMD_MODE) + (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define. + (arc_init_reg_tables): Accept new ARC HS SIMD modes. + (arc_init_builtins): Add new SIMD builtin types. + (arc_split_move): Handle 64 bit vector moves. + * config/arc/arc.h (TARGET_PLUS_DMPY, TARGET_PLUS_MACD) + (TARGET_PLUS_QMACW): Define. + * config/arc/builtins.def (QMACH, QMACHU, QMPYH, QMPYHU, DMACH) + (DMACHU, DMPYH, DMPYHU, DMACWH, DMACWHU, VMAC2H, VMAC2HU, VMPY2H) + (VMPY2HU, VADDSUB2H, VSUBADD2H, VADDSUB, VSUBADD, VADDSUB4H) + (VSUBADD4H): New builtins. + * config/arc/simdext.md: Add new ARC HS SIMD instructions. + * testsuite/gcc.target/arc/builtin_simdarc.c: New file. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235551 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 20 + + gcc/config/arc/arc.c | 112 ++++- + gcc/config/arc/arc.h | 6 + + gcc/config/arc/builtins.def | 27 ++ + gcc/config/arc/simdext.md | 571 +++++++++++++++++++++++++ + gcc/testsuite/gcc.target/arc/builtin_simdarc.c | 38 ++ + 6 files changed, 767 insertions(+), 7 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/builtin_simdarc.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 06ebfb1a548a..a88e2f2ff8be 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,23 @@ ++2016-04-28 Claudiu Zissulescu ++ ++ * config/arc/arc.c (arc_vector_mode_supported_p): Add support for ++ the new ARC HS SIMD instructions. ++ (arc_preferred_simd_mode): New function. ++ (arc_autovectorize_vector_sizes): Likewise. ++ (TARGET_VECTORIZE_PREFERRED_SIMD_MODE) ++ (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Define. ++ (arc_init_reg_tables): Accept new ARC HS SIMD modes. ++ (arc_init_builtins): Add new SIMD builtin types. ++ (arc_split_move): Handle 64 bit vector moves. ++ * config/arc/arc.h (TARGET_PLUS_DMPY, TARGET_PLUS_MACD) ++ (TARGET_PLUS_QMACW): Define. ++ * config/arc/builtins.def (QMACH, QMACHU, QMPYH, QMPYHU, DMACH) ++ (DMACHU, DMPYH, DMPYHU, DMACWH, DMACWHU, VMAC2H, VMAC2HU, VMPY2H) ++ (VMPY2HU, VADDSUB2H, VSUBADD2H, VADDSUB, VSUBADD, VADDSUB4H) ++ (VSUBADD4H): New builtins. ++ * config/arc/simdext.md: Add new ARC HS SIMD instructions. ++ * testsuite/gcc.target/arc/builtin_simdarc.c: New file. ++ + 2016-12-21 Release Manager + + * GCC 6.3.0 released. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index d60db502ef85..d120946a5f2f 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -247,16 +247,47 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT, + static bool + arc_vector_mode_supported_p (machine_mode mode) + { +- if (!TARGET_SIMD_SET) +- return false; ++ switch (mode) ++ { ++ case V2HImode: ++ return TARGET_PLUS_DMPY; ++ case V4HImode: ++ case V2SImode: ++ return TARGET_PLUS_QMACW; ++ case V4SImode: ++ case V8HImode: ++ return TARGET_SIMD_SET; + +- if ((mode == V4SImode) +- || (mode == V8HImode)) +- return true; ++ default: ++ return false; ++ } ++} + +- return false; ++/* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */ ++ ++static enum machine_mode ++arc_preferred_simd_mode (enum machine_mode mode) ++{ ++ switch (mode) ++ { ++ case HImode: ++ return TARGET_PLUS_QMACW ? V4HImode : V2HImode; ++ case SImode: ++ return V2SImode; ++ ++ default: ++ return word_mode; ++ } + } + ++/* Implements target hook ++ TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */ ++ ++static unsigned int ++arc_autovectorize_vector_sizes (void) ++{ ++ return TARGET_PLUS_QMACW ? (8 | 4) : 0; ++} + + /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */ + static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED; +@@ -345,6 +376,12 @@ static void arc_finalize_pic (void); + #undef TARGET_VECTOR_MODE_SUPPORTED_P + #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p + ++#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE ++#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode ++ ++#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES ++#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes ++ + #undef TARGET_CAN_USE_DOLOOP_P + #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p + +@@ -1214,7 +1251,12 @@ arc_init_reg_tables (void) + arc_mode_class[i] = 0; + break; + case MODE_VECTOR_INT: +- arc_mode_class [i] = (1<< (int) V_MODE); ++ if (GET_MODE_SIZE (m) == 4) ++ arc_mode_class[i] = (1 << (int) S_MODE); ++ else if (GET_MODE_SIZE (m) == 8) ++ arc_mode_class[i] = (1 << (int) D_MODE); ++ else ++ arc_mode_class[i] = (1 << (int) V_MODE); + break; + case MODE_CC: + default: +@@ -5277,6 +5319,15 @@ arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED) + static void + arc_init_builtins (void) + { ++ tree V4HI_type_node; ++ tree V2SI_type_node; ++ tree V2HI_type_node; ++ ++ /* Vector types based on HS SIMD elements. */ ++ V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode); ++ V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode); ++ V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode); ++ + tree pcvoid_type_node + = build_pointer_type (build_qualified_type (void_type_node, + TYPE_QUAL_CONST)); +@@ -5341,6 +5392,28 @@ arc_init_builtins (void) + tree v8hi_ftype_v8hi + = build_function_type_list (V8HI_type_node, V8HI_type_node, + NULL_TREE); ++ /* ARCv2 SIMD types. */ ++ tree long_ftype_v4hi_v4hi ++ = build_function_type_list (long_long_integer_type_node, ++ V4HI_type_node, V4HI_type_node, NULL_TREE); ++ tree int_ftype_v2hi_v2hi ++ = build_function_type_list (integer_type_node, ++ V2HI_type_node, V2HI_type_node, NULL_TREE); ++ tree v2si_ftype_v2hi_v2hi ++ = build_function_type_list (V2SI_type_node, ++ V2HI_type_node, V2HI_type_node, NULL_TREE); ++ tree v2hi_ftype_v2hi_v2hi ++ = build_function_type_list (V2HI_type_node, ++ V2HI_type_node, V2HI_type_node, NULL_TREE); ++ tree v2si_ftype_v2si_v2si ++ = build_function_type_list (V2SI_type_node, ++ V2SI_type_node, V2SI_type_node, NULL_TREE); ++ tree v4hi_ftype_v4hi_v4hi ++ = build_function_type_list (V4HI_type_node, ++ V4HI_type_node, V4HI_type_node, NULL_TREE); ++ tree long_ftype_v2si_v2hi ++ = build_function_type_list (long_long_integer_type_node, ++ V2SI_type_node, V2HI_type_node, NULL_TREE); + + /* Add the builtins. */ + #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \ +@@ -8706,6 +8779,31 @@ arc_split_move (rtx *operands) + return; + } + ++ if (TARGET_PLUS_QMACW ++ && GET_CODE (operands[1]) == CONST_VECTOR) ++ { ++ HOST_WIDE_INT intval0, intval1; ++ if (GET_MODE (operands[1]) == V2SImode) ++ { ++ intval0 = INTVAL (XVECEXP (operands[1], 0, 0)); ++ intval1 = INTVAL (XVECEXP (operands[1], 0, 1)); ++ } ++ else ++ { ++ intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16; ++ intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF; ++ intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16; ++ intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF; ++ } ++ xop[0] = gen_rtx_REG (SImode, REGNO (operands[0])); ++ xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1); ++ xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode)); ++ xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode)); ++ emit_move_insn (xop[0], xop[2]); ++ emit_move_insn (xop[3], xop[1]); ++ return; ++ } ++ + for (i = 0; i < 2; i++) + { + if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0))) +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 1c2a38d4acfc..5100a5b8f821 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1724,6 +1724,12 @@ enum + /* Any multiplication feature macro. */ + #define TARGET_ANY_MPY \ + (TARGET_MPY || TARGET_MUL64_SET || TARGET_MULMAC_32BY16_SET) ++/* PLUS_DMPY feature macro. */ ++#define TARGET_PLUS_DMPY ((arc_mpy_option > 6) && TARGET_HS) ++/* PLUS_MACD feature macro. */ ++#define TARGET_PLUS_MACD ((arc_mpy_option > 7) && TARGET_HS) ++/* PLUS_QMACW feature macro. */ ++#define TARGET_PLUS_QMACW ((arc_mpy_option > 8) && TARGET_HS) + + /* ARC600 and ARC601 feature macro. */ + #define TARGET_ARC600_FAMILY (TARGET_ARC600 || TARGET_ARC601) +diff --git a/gcc/config/arc/builtins.def b/gcc/config/arc/builtins.def +index 19be1d218520..8c71d30a459a 100644 +--- a/gcc/config/arc/builtins.def ++++ b/gcc/config/arc/builtins.def +@@ -193,3 +193,30 @@ DEF_BUILTIN (VINTI, 1, void_ftype_int, vinti_insn, TARGET_SIMD_SET) + + /* END SIMD marker. */ + DEF_BUILTIN (SIMD_END, 0, void_ftype_void, nothing, 0) ++ ++/* ARCv2 SIMD instructions that use/clobber the accumulator reg. */ ++DEF_BUILTIN (QMACH, 2, long_ftype_v4hi_v4hi, qmach, TARGET_PLUS_QMACW) ++DEF_BUILTIN (QMACHU, 2, long_ftype_v4hi_v4hi, qmachu, TARGET_PLUS_QMACW) ++DEF_BUILTIN (QMPYH, 2, long_ftype_v4hi_v4hi, qmpyh, TARGET_PLUS_QMACW) ++DEF_BUILTIN (QMPYHU, 2, long_ftype_v4hi_v4hi, qmpyhu, TARGET_PLUS_QMACW) ++ ++DEF_BUILTIN (DMACH, 2, int_ftype_v2hi_v2hi, dmach, TARGET_PLUS_DMPY) ++DEF_BUILTIN (DMACHU, 2, int_ftype_v2hi_v2hi, dmachu, TARGET_PLUS_DMPY) ++DEF_BUILTIN (DMPYH, 2, int_ftype_v2hi_v2hi, dmpyh, TARGET_PLUS_DMPY) ++DEF_BUILTIN (DMPYHU, 2, int_ftype_v2hi_v2hi, dmpyhu, TARGET_PLUS_DMPY) ++ ++DEF_BUILTIN (DMACWH, 2, long_ftype_v2si_v2hi, dmacwh, TARGET_PLUS_QMACW) ++DEF_BUILTIN (DMACWHU, 2, long_ftype_v2si_v2hi, dmacwhu, TARGET_PLUS_QMACW) ++ ++DEF_BUILTIN (VMAC2H, 2, v2si_ftype_v2hi_v2hi, vmac2h, TARGET_PLUS_MACD) ++DEF_BUILTIN (VMAC2HU, 2, v2si_ftype_v2hi_v2hi, vmac2hu, TARGET_PLUS_MACD) ++DEF_BUILTIN (VMPY2H, 2, v2si_ftype_v2hi_v2hi, vmpy2h, TARGET_PLUS_MACD) ++DEF_BUILTIN (VMPY2HU, 2, v2si_ftype_v2hi_v2hi, vmpy2hu, TARGET_PLUS_MACD) ++ ++/* Combined add/sub HS SIMD instructions. */ ++DEF_BUILTIN (VADDSUB2H, 2, v2hi_ftype_v2hi_v2hi, addsubv2hi3, TARGET_PLUS_DMPY) ++DEF_BUILTIN (VSUBADD2H, 2, v2hi_ftype_v2hi_v2hi, subaddv2hi3, TARGET_PLUS_DMPY) ++DEF_BUILTIN (VADDSUB, 2, v2si_ftype_v2si_v2si, addsubv2si3, TARGET_PLUS_QMACW) ++DEF_BUILTIN (VSUBADD, 2, v2si_ftype_v2si_v2si, subaddv2si3, TARGET_PLUS_QMACW) ++DEF_BUILTIN (VADDSUB4H, 2, v4hi_ftype_v4hi_v4hi, addsubv4hi3, TARGET_PLUS_QMACW) ++DEF_BUILTIN (VSUBADD4H, 2, v4hi_ftype_v4hi_v4hi, subaddv4hi3, TARGET_PLUS_QMACW) +diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md +index 9fd9d62e0483..51869e367726 100644 +--- a/gcc/config/arc/simdext.md ++++ b/gcc/config/arc/simdext.md +@@ -1288,3 +1288,574 @@ + [(set_attr "type" "simd_vcontrol") + (set_attr "length" "4") + (set_attr "cond" "nocond")]) ++ ++;; New ARCv2 SIMD extensions ++ ++;;64-bit vectors of halwords and words ++(define_mode_iterator VWH [V4HI V2SI]) ++ ++;;double element vectors ++(define_mode_iterator VDV [V2HI V2SI]) ++(define_mode_attr V_addsub [(V2HI "HI") (V2SI "SI")]) ++(define_mode_attr V_addsub_suffix [(V2HI "2h") (V2SI "")]) ++ ++;;all vectors ++(define_mode_iterator VCT [V2HI V4HI V2SI]) ++(define_mode_attr V_suffix [(V2HI "2h") (V4HI "4h") (V2SI "2")]) ++ ++;; Widening operations. ++(define_code_iterator SE [sign_extend zero_extend]) ++(define_code_attr V_US [(sign_extend "s") (zero_extend "u")]) ++(define_code_attr V_US_suffix [(sign_extend "") (zero_extend "u")]) ++ ++ ++;; Move patterns ++(define_expand "movv2hi" ++ [(set (match_operand:V2HI 0 "move_dest_operand" "") ++ (match_operand:V2HI 1 "general_operand" ""))] ++ "" ++ "{ ++ if (prepare_move_operands (operands, V2HImode)) ++ DONE; ++ }") ++ ++(define_insn_and_split "*movv2hi_insn" ++ [(set (match_operand:V2HI 0 "nonimmediate_operand" "=r,r,r,m") ++ (match_operand:V2HI 1 "general_operand" "i,r,m,r"))] ++ "(register_operand (operands[0], V2HImode) ++ || register_operand (operands[1], V2HImode))" ++ "@ ++ # ++ mov%? %0, %1 ++ ld%U1%V1 %0,%1 ++ st%U0%V0 %1,%0" ++ "reload_completed && GET_CODE (operands[1]) == CONST_VECTOR" ++ [(set (match_dup 0) (match_dup 2))] ++ { ++ HOST_WIDE_INT intval = INTVAL (XVECEXP (operands[1], 0, 1)) << 16; ++ intval |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF; ++ ++ operands[0] = gen_rtx_REG (SImode, REGNO (operands[0])); ++ operands[2] = GEN_INT (trunc_int_for_mode (intval, SImode)); ++ } ++ [(set_attr "type" "move,move,load,store") ++ (set_attr "predicable" "yes,yes,no,no") ++ (set_attr "iscompact" "false,false,false,false") ++ ]) ++ ++(define_expand "movmisalignv2hi" ++ [(set (match_operand:V2HI 0 "general_operand" "") ++ (match_operand:V2HI 1 "general_operand" ""))] ++ "" ++{ ++ if (!register_operand (operands[0], V2HImode) ++ && !register_operand (operands[1], V2HImode)) ++ operands[1] = force_reg (V2HImode, operands[1]); ++}) ++ ++(define_expand "mov" ++ [(set (match_operand:VWH 0 "move_dest_operand" "") ++ (match_operand:VWH 1 "general_operand" ""))] ++ "" ++ "{ ++ if (GET_CODE (operands[0]) == MEM) ++ operands[1] = force_reg (mode, operands[1]); ++ }") ++ ++(define_insn_and_split "*mov_insn" ++ [(set (match_operand:VWH 0 "move_dest_operand" "=r,r,r,m") ++ (match_operand:VWH 1 "general_operand" "i,r,m,r"))] ++ "TARGET_PLUS_QMACW ++ && (register_operand (operands[0], mode) ++ || register_operand (operands[1], mode))" ++ "* ++{ ++ switch (which_alternative) ++ { ++ default: ++ return \"#\"; ++ ++ case 1: ++ return \"vadd2 %0, %1, 0\"; ++ ++ case 2: ++ if (TARGET_LL64) ++ return \"ldd%U1%V1 %0,%1\"; ++ return \"#\"; ++ ++ case 3: ++ if (TARGET_LL64) ++ return \"std%U0%V0 %1,%0\"; ++ return \"#\"; ++ } ++}" ++ "reload_completed" ++ [(const_int 0)] ++ { ++ arc_split_move (operands); ++ DONE; ++ } ++ [(set_attr "type" "move,move,load,store") ++ (set_attr "predicable" "yes,no,no,no") ++ (set_attr "iscompact" "false,false,false,false") ++ ]) ++ ++(define_expand "movmisalign" ++ [(set (match_operand:VWH 0 "general_operand" "") ++ (match_operand:VWH 1 "general_operand" ""))] ++ "" ++{ ++ if (!register_operand (operands[0], mode) ++ && !register_operand (operands[1], mode)) ++ operands[1] = force_reg (mode, operands[1]); ++}) ++ ++(define_insn "bswapv2hi2" ++ [(set (match_operand:V2HI 0 "register_operand" "=r,r") ++ (bswap:V2HI (match_operand:V2HI 1 "nonmemory_operand" "r,i")))] ++ "TARGET_V2 && TARGET_SWAP" ++ "swape %0, %1" ++ [(set_attr "length" "4,8") ++ (set_attr "type" "two_cycle_core")]) ++ ++;; Simple arithmetic insns ++(define_insn "add3" ++ [(set (match_operand:VCT 0 "register_operand" "=r,r") ++ (plus:VCT (match_operand:VCT 1 "register_operand" "0,r") ++ (match_operand:VCT 2 "register_operand" "r,r")))] ++ "TARGET_PLUS_DMPY" ++ "vadd%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "sub3" ++ [(set (match_operand:VCT 0 "register_operand" "=r,r") ++ (minus:VCT (match_operand:VCT 1 "register_operand" "0,r") ++ (match_operand:VCT 2 "register_operand" "r,r")))] ++ "TARGET_PLUS_DMPY" ++ "vsub%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++;; Combined arithmetic ops ++(define_insn "addsub3" ++ [(set (match_operand:VDV 0 "register_operand" "=r,r") ++ (vec_concat:VDV ++ (plus: (vec_select: (match_operand:VDV 1 "register_operand" "0,r") ++ (parallel [(const_int 0)])) ++ (vec_select: (match_operand:VDV 2 "register_operand" "r,r") ++ (parallel [(const_int 0)]))) ++ (minus: (vec_select: (match_dup 1) (parallel [(const_int 1)])) ++ (vec_select: (match_dup 2) (parallel [(const_int 1)])))))] ++ "TARGET_PLUS_DMPY" ++ "vaddsub%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "subadd3" ++ [(set (match_operand:VDV 0 "register_operand" "=r,r") ++ (vec_concat:VDV ++ (minus: (vec_select: (match_operand:VDV 1 "register_operand" "0,r") ++ (parallel [(const_int 0)])) ++ (vec_select: (match_operand:VDV 2 "register_operand" "r,r") ++ (parallel [(const_int 0)]))) ++ (plus: (vec_select: (match_dup 1) (parallel [(const_int 1)])) ++ (vec_select: (match_dup 2) (parallel [(const_int 1)])))))] ++ "TARGET_PLUS_DMPY" ++ "vsubadd%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "addsubv4hi3" ++ [(set (match_operand:V4HI 0 "even_register_operand" "=r,r") ++ (vec_concat:V4HI ++ (vec_concat:V2HI ++ (plus:HI (vec_select:HI (match_operand:V4HI 1 "even_register_operand" "0,r") ++ (parallel [(const_int 0)])) ++ (vec_select:HI (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (parallel [(const_int 0)]))) ++ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))) ++ (vec_concat:V2HI ++ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))) ++ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 3)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) ++ ))] ++ "TARGET_PLUS_QMACW" ++ "vaddsub4h%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "subaddv4hi3" ++ [(set (match_operand:V4HI 0 "even_register_operand" "=r,r") ++ (vec_concat:V4HI ++ (vec_concat:V2HI ++ (minus:HI (vec_select:HI (match_operand:V4HI 1 "even_register_operand" "0,r") ++ (parallel [(const_int 0)])) ++ (vec_select:HI (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (parallel [(const_int 0)]))) ++ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 1)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))) ++ (vec_concat:V2HI ++ (minus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 2)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 2)]))) ++ (plus:HI (vec_select:HI (match_dup 1) (parallel [(const_int 3)])) ++ (vec_select:HI (match_dup 2) (parallel [(const_int 3)])))) ++ ))] ++ "TARGET_PLUS_QMACW" ++ "vsubadd4h%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++;; Multiplication ++(define_insn "dmpyh" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (plus:SI ++ (mult:SI ++ (SE:SI ++ (vec_select:HI (match_operand:V2HI 1 "register_operand" "0,r") ++ (parallel [(const_int 0)]))) ++ (SE:SI ++ (vec_select:HI (match_operand:V2HI 2 "register_operand" "r,r") ++ (parallel [(const_int 0)])))) ++ (mult:SI ++ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) ++ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))) ++ (set (reg:DI ARCV2_ACC) ++ (zero_extend:DI ++ (plus:SI ++ (mult:SI ++ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 0)]))) ++ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 0)])))) ++ (mult:SI ++ (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) ++ (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))))] ++ "TARGET_PLUS_DMPY" ++ "dmpy%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++;; We can use dmac as well here. To be investigated which version ++;; brings more. ++(define_expand "sdot_prodv2hi" ++ [(match_operand:SI 0 "register_operand" "") ++ (match_operand:V2HI 1 "register_operand" "") ++ (match_operand:V2HI 2 "register_operand" "") ++ (match_operand:SI 3 "register_operand" "")] ++ "TARGET_PLUS_DMPY" ++{ ++ rtx t = gen_reg_rtx (SImode); ++ emit_insn (gen_dmpyh (t, operands[1], operands[2])); ++ emit_insn (gen_addsi3 (operands[0], operands[3], t)); ++ DONE; ++}) ++ ++(define_expand "udot_prodv2hi" ++ [(match_operand:SI 0 "register_operand" "") ++ (match_operand:V2HI 1 "register_operand" "") ++ (match_operand:V2HI 2 "register_operand" "") ++ (match_operand:SI 3 "register_operand" "")] ++ "TARGET_PLUS_DMPY" ++{ ++ rtx t = gen_reg_rtx (SImode); ++ emit_insn (gen_dmpyhu (t, operands[1], operands[2])); ++ emit_insn (gen_addsi3 (operands[0], operands[3], t)); ++ DONE; ++}) ++ ++(define_insn "arc_vec_mult_lo_v4hi" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "0,r") ++ (parallel [(const_int 0) (const_int 1)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (parallel [(const_int 0) (const_int 1)]))))) ++ (set (reg:V2SI ARCV2_ACC) ++ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1) ++ (parallel [(const_int 0) (const_int 1)]))) ++ (SE:V2SI (vec_select:V2HI (match_dup 2) ++ (parallel [(const_int 0) (const_int 1)]))))) ++ ] ++ "TARGET_PLUS_MACD" ++ "vmpy2h%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "arc_vec_multacc_lo_v4hi" ++ [(set (reg:V2SI ARCV2_ACC) ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 0 "even_register_operand" "r") ++ (parallel [(const_int 0) (const_int 1)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "r") ++ (parallel [(const_int 0) (const_int 1)]))))) ++ ] ++ "TARGET_PLUS_MACD" ++ "vmpy2h%? 0, %0, %1" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_expand "vec_widen_mult_lo_v4hi" ++ [(set (match_operand:V2SI 0 "even_register_operand" "") ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "") ++ (parallel [(const_int 0) (const_int 1)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 2 "even_register_operand" "") ++ (parallel [(const_int 0) (const_int 1)])))))] ++ "TARGET_PLUS_QMACW" ++ { ++ emit_insn (gen_arc_vec_mult_lo_v4hi (operands[0], ++ operands[1], ++ operands[2])); ++ DONE; ++ } ++) ++ ++(define_insn "arc_vec_mult_hi_v4hi" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "0,r") ++ (parallel [(const_int 2) (const_int 3)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (parallel [(const_int 2) (const_int 3)]))))) ++ (set (reg:V2SI ARCV2_ACC) ++ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1) ++ (parallel [(const_int 2) (const_int 3)]))) ++ (SE:V2SI (vec_select:V2HI (match_dup 2) ++ (parallel [(const_int 2) (const_int 3)]))))) ++ ] ++ "TARGET_PLUS_QMACW" ++ "vmpy2h%? %0, %R1, %R2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_expand "vec_widen_mult_hi_v4hi" ++ [(set (match_operand:V2SI 0 "even_register_operand" "") ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "") ++ (parallel [(const_int 2) (const_int 3)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 2 "even_register_operand" "") ++ (parallel [(const_int 2) (const_int 3)])))))] ++ "TARGET_PLUS_MACD" ++ { ++ emit_insn (gen_arc_vec_mult_hi_v4hi (operands[0], ++ operands[1], ++ operands[2])); ++ DONE; ++ } ++) ++ ++(define_insn "arc_vec_mac_hi_v4hi" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (plus:V2SI ++ (reg:V2SI ARCV2_ACC) ++ (mult:V2SI (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 1 "even_register_operand" "0,r") ++ (parallel [(const_int 2) (const_int 3)]))) ++ (SE:V2SI (vec_select:V2HI ++ (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (parallel [(const_int 2) (const_int 3)])))))) ++ (set (reg:V2SI ARCV2_ACC) ++ (plus:V2SI ++ (reg:V2SI ARCV2_ACC) ++ (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1) ++ (parallel [(const_int 2) (const_int 3)]))) ++ (SE:V2SI (vec_select:V2HI (match_dup 2) ++ (parallel [(const_int 2) (const_int 3)])))))) ++ ] ++ "TARGET_PLUS_MACD" ++ "vmac2h%? %0, %R1, %R2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++;; Builtins ++(define_insn "dmach" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (unspec:SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_DMACH)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_DMPY" ++ "dmach%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "dmachu" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (unspec:SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_DMACHU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_DMPY" ++ "dmachu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "dmacwh" ++ [(set (match_operand:DI 0 "even_register_operand" "=r,r") ++ (unspec:DI [(match_operand:V2SI 1 "even_register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_DMACWH)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "dmacwh%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "dmacwhu" ++ [(set (match_operand:DI 0 "register_operand" "=r,r") ++ (unspec:DI [(match_operand:V2SI 1 "even_register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_DMACWHU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "dmacwhu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "vmac2h" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_VMAC2H)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_MACD" ++ "vmac2h%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "vmac2hu" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_VMAC2HU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_MACD" ++ "vmac2hu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "vmpy2h" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r")] ++ UNSPEC_ARC_VMPY2H)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_MACD" ++ "vmpy2h%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "vmpy2hu" ++ [(set (match_operand:V2SI 0 "even_register_operand" "=r,r") ++ (unspec:V2SI [(match_operand:V2HI 1 "register_operand" "0,r") ++ (match_operand:V2HI 2 "register_operand" "r,r")] ++ UNSPEC_ARC_VMPY2HU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_MACD" ++ "vmpy2hu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "qmach" ++ [(set (match_operand:DI 0 "even_register_operand" "=r,r") ++ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r") ++ (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_QMACH)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "qmach%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "qmachu" ++ [(set (match_operand:DI 0 "even_register_operand" "=r,r") ++ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r") ++ (match_operand:V4HI 2 "even_register_operand" "r,r") ++ (reg:DI ARCV2_ACC)] ++ UNSPEC_ARC_QMACHU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "qmachu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "qmpyh" ++ [(set (match_operand:DI 0 "even_register_operand" "=r,r") ++ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r") ++ (match_operand:V4HI 2 "even_register_operand" "r,r")] ++ UNSPEC_ARC_QMPYH)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "qmpyh%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "qmpyhu" ++ [(set (match_operand:DI 0 "even_register_operand" "=r,r") ++ (unspec:DI [(match_operand:V4HI 1 "even_register_operand" "0,r") ++ (match_operand:V4HI 2 "even_register_operand" "r,r")] ++ UNSPEC_ARC_QMPYHU)) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_QMACW" ++ "qmpyhu%? %0, %1, %2" ++ [(set_attr "length" "4") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) +diff --git a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c +new file mode 100644 +index 000000000000..68aae40ca58e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c +@@ -0,0 +1,38 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -mmpy-option=9" } */ ++ ++#define STEST(name, rettype, op1type, op2type) \ ++ rettype test_ ## name \ ++ (op1type a, op2type b) \ ++ { \ ++ return __builtin_arc_ ## name (a, b); \ ++ } ++ ++typedef short v2hi __attribute__ ((vector_size (4))); ++typedef short v4hi __attribute__ ((vector_size (8))); ++typedef int v2si __attribute__ ((vector_size (8))); ++ ++STEST (qmach, long long, v4hi, v4hi) ++STEST (qmachu, long long, v4hi, v4hi) ++STEST (qmpyh, long long, v4hi, v4hi) ++STEST (qmpyhu, long long, v4hi, v4hi) ++ ++STEST (dmach, int, v2hi, v2hi) ++STEST (dmachu, int, v2hi, v2hi) ++STEST (dmpyh, int, v2hi, v2hi) ++STEST (dmpyhu, int, v2hi, v2hi) ++ ++STEST (dmacwh, long, v2si, v2hi) ++STEST (dmacwhu, long, v2si, v2hi) ++ ++STEST (vmac2h, v2si, v2hi, v2hi) ++STEST (vmac2hu, v2si, v2hi, v2hi) ++STEST (vmpy2h, v2si, v2hi, v2hi) ++STEST (vmpy2hu, v2si, v2hi, v2hi) ++ ++STEST (vaddsub2h, v2hi, v2hi, v2hi) ++STEST (vsubadd2h, v2hi, v2hi, v2hi) ++STEST (vaddsub, v2si, v2si, v2si) ++STEST (vsubadd, v2si, v2si, v2si) ++STEST (vaddsub4h, v4hi, v4hi, v4hi) ++STEST (vsubadd4h, v4hi, v4hi, v4hi) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0002-ARC-LIBGCC-Add-TLS-support.patch b/toolchain/gcc/patches/6.3.0/0002-ARC-LIBGCC-Add-TLS-support.patch new file mode 100644 index 0000000..332014f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0002-ARC-LIBGCC-Add-TLS-support.patch @@ -0,0 +1,144 @@ +From 37ceb52d577de40f4497bd51baa328b9c1a7a860 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 11:53:34 +0000 +Subject: [PATCH 02/89] [ARC/LIBGCC] Add TLS support. + +libgcc/ +2016-04-28 Claudiu Zissulescu + Joern Rennecke + + * config/arc/crttls.S: New file. + * config/arc/t-arc: New rule. + * config.host (arc*-*-elf*, arc*-*-linux*): Add crttls.o. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235558 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + libgcc/ChangeLog | 7 +++++ + libgcc/config.host | 2 ++ + libgcc/config/arc/crttls.S | 67 ++++++++++++++++++++++++++++++++++++++++++++++ + libgcc/config/arc/t-arc | 3 +++ + 4 files changed, 79 insertions(+) + create mode 100644 libgcc/config/arc/crttls.S + +diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog +index 8e5e308c7ddc..0993d6226cd2 100644 +--- a/libgcc/ChangeLog ++++ b/libgcc/ChangeLog +@@ -1,3 +1,10 @@ ++2016-04-28 Claudiu Zissulescu ++ Joern Rennecke ++ ++ * config/arc/crttls.S: New file. ++ * config/arc/t-arc: New rule. ++ * config.host (arc*-*-elf*, arc*-*-linux*): Add crttls.o. ++ + 2016-12-21 Release Manager + + * GCC 6.3.0 released. +diff --git a/libgcc/config.host b/libgcc/config.host +index 124f2ceaefda..4e02765fce74 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -367,10 +367,12 @@ alpha*-dec-*vms*) + arc*-*-elf*) + tmake_file="arc/t-arc-newlib arc/t-arc" + extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o" ++ extra_parts="${extra_parts} crttls.o" + ;; + arc*-*-linux-uclibc*) + tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc700-uClibc arc/t-arc" + extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o" ++ extra_parts="${extra_parts} crttls.o" + ;; + arm-wrs-vxworks) + tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp" +diff --git a/libgcc/config/arc/crttls.S b/libgcc/config/arc/crttls.S +new file mode 100644 +index 000000000000..512c1df53c02 +--- /dev/null ++++ b/libgcc/config/arc/crttls.S +@@ -0,0 +1,67 @@ ++; newlib tls glue code for Synopsys DesignWare ARC cpu. ++ ++/* Copyright (C) 2016 Free Software Foundation, Inc. ++ Contributor: Joern Rennecke ++ on behalf of Synopsys 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. ++ ++Under Section 7 of GPL version 3, you are granted additional ++permissions described in the GCC Runtime Library Exception, version ++3.1, as published by the Free Software Foundation. ++ ++You should have received a copy of the GNU General Public License and ++a copy of the GCC Runtime Library Exception along with this program; ++see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ++. */ ++ ++/* As a special exception, if you link this library with other files, ++ some of which are compiled with GCC, to produce an executable, ++ this library does not by itself cause the resulting executable ++ to be covered by the GNU General Public License. ++ This exception does not however invalidate any other reasons why ++ the executable file might be covered by the GNU General Public License. */ ++ ++ ++#if (__ARC_TLS_REGNO__ != -1) ++ /* ANSI concatenation macros. */ ++ ++#define CONCAT1(a, b) CONCAT2(a, b) ++#define CONCAT2(a, b) a ## b ++ ++ /* Use the right prefix for global labels. */ ++ ++#define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) ++ ++#define FUNC(X) .type SYM(X),@function ++#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X ++#define ENDFUNC(X) ENDFUNC0(X) ++ ++ .global SYM(__read_tp) ++SYM(__read_tp): ++ FUNC(__read_tp) ++ mov r0, CONCAT1 (r, __ARC_TLS_REGNO__) ++ nop ++ j [blink] ++ ENDFUNC(__read_tp) ++ ++ .section .init ++ mov CONCAT1 (r, __ARC_TLS_REGNO__),__main_tcb_end+256 ++ ++ .section .tbss ++__main_tcb: ++ .long 0 ++ .long 0 ++__main_tcb_end: ++ ++#endif /*__ARC_TLS_REGNO__ != -1 */ +diff --git a/libgcc/config/arc/t-arc b/libgcc/config/arc/t-arc +index 7ceb694f69fd..3523aedec13b 100644 +--- a/libgcc/config/arc/t-arc ++++ b/libgcc/config/arc/t-arc +@@ -68,6 +68,9 @@ crtg.o: $(srcdir)/config/arc/crtg.S + crtgend.o: $(srcdir)/config/arc/crtgend.S + $(crt_compile) -c -x assembler-with-cpp $< + ++crttls.o: $(srcdir)/config/arc/crttls.S ++ $(crt_compile) -c -x assembler-with-cpp $< ++ + mcount.o: $(srcdir)/config/arc/gmon/mcount.c + $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< \ + -fcall-saved-r0 -fcall-saved-r1 -fcall-saved-r2 -fcall-saved-r3 \ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0003-ARC-Add-TLS-support.patch b/toolchain/gcc/patches/6.3.0/0003-ARC-Add-TLS-support.patch new file mode 100644 index 0000000..6eaf994 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0003-ARC-Add-TLS-support.patch @@ -0,0 +1,1147 @@ +From e42098397e6646a8fa0a3c63e662c274a93bc464 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 11:53:46 +0000 +Subject: [PATCH 03/89] [ARC] Add TLS support. + +gcc/ +2016-04-28 Claudiu Zissulescu + Joern Rennecke + + * config/arc/arc-protos.h (arc_legitimize_pic_address): Remove + declaration. + (emit_pic_move): Remove. + (arc_eh_uses, insn_is_tls_gd_dispatch): Declare. + * config/arc/arc.c (emit_pic_move): Removed. + (TARGET_HAVE_TLS): Define. + (arc_conditional_register_usage): Test for arc_tp_regno. + (arc_print_operand, arc_print_operand_address): Handle TLS + unspecs. + (arc_needs_pcl_p): New function. + (arc_legitimate_pc_offset_p): Use arc_needs_pcl_p. + (arc_legitimate_pic_addr_p): Handle TLS unspecs. + (arc_raw_symbolic_reference_mentioned_p): Likewise. + (arc_get_tp, arc_emit_call_tls_get_addr): New function. + (arc_legitimize_tls_address): Likewise. + (DTPOFF_ZERO_SYM): Define. + (arc_legitimize_pic_address): Make it static, handle TLS cases. + (arc_output_pic_addr_const): Print TLS unspecs. + (prepare_pic_move): New function, replaces emit_pic_move. + (arc_legitimate_constant_p): Handle TLS unspecs. + (arc_legitimate_address_p): Likewise. + (arc_rewrite_small_data_p): Use assert for TLS constants. + (prepare_move_operands): Use prepare_pic_move. + (arc_legitimize_address): Legitimize tls addresses. + (arc_epilogue_uses): Check for arc_tp_regno. + (arc_eh_uses, insn_is_tls_gd_dispatch): New function. + * config/arc/arc.h [DEFAULT_LIBC != LIBC_UCLIBC] (EXTRA_SPECS): + Define. + [DEFAULT_LIBC != LIBC_UCLIBC] (ARC_TLS_EXTRA_START_SPEC): + Likewise. + [DEFAULT_LIBC != LIBC_UCLIBC] (STARTFILE_SPEC): Add + %(arc_tls_extra_start_spec). + (TARGET_CPU_CPP_BUILTINS): Define __ARC_TLS_REGNO__. + (REGNO_OK_FOR_BASE_P): Check for arc_tp_regno. + (EH_USES): Define. + (INSN_REFERENCES_ARE_DELAYED): Use insn_is_tls_gd_dispatch. + * config/arc/arc.md (UNSPEC_TLS_GD, UNSPEC_TLS_LD, UNSPEC_TLS_IE) + (UNSPEC_TLS_OFF): Add. + (R10_REG): Define. + (tls_load_tp_soft, tls_gd_load, tls_gd_get_addr, tls_gd_dispatch) + (get_thread_pointersi): New patterns. + * config/arc/arc.opt (mtp-regno): New option. + * config/arc/predicates.md (move_src_operand): Handle TLS symbols. + (move_dest_operand): Likewise. + * configure: Regenerate. + * configure.ac: Add arc*-*-* case to test for tls. + * doc/invoke.texi (ARC options): Document mtp-regno. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235559 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 51 +++++ + gcc/config/arc/arc-protos.h | 4 +- + gcc/config/arc/arc.c | 505 +++++++++++++++++++++++++++++++------------ + gcc/config/arc/arc.h | 22 +- + gcc/config/arc/arc.md | 71 ++++++ + gcc/config/arc/arc.opt | 7 + + gcc/config/arc/predicates.md | 15 +- + gcc/configure | 6 + + gcc/configure.ac | 6 + + gcc/doc/invoke.texi | 6 +- + 10 files changed, 545 insertions(+), 148 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index a88e2f2ff8be..047bc20a9790 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,4 +1,55 @@ + 2016-04-28 Claudiu Zissulescu ++ Joern Rennecke ++ ++ * config/arc/arc-protos.h (arc_legitimize_pic_address): Remove ++ declaration. ++ (emit_pic_move): Remove. ++ (arc_eh_uses, insn_is_tls_gd_dispatch): Declare. ++ * config/arc/arc.c (emit_pic_move): Removed. ++ (TARGET_HAVE_TLS): Define. ++ (arc_conditional_register_usage): Test for arc_tp_regno. ++ (arc_print_operand, arc_print_operand_address): Handle TLS ++ unspecs. ++ (arc_needs_pcl_p): New function. ++ (arc_legitimate_pc_offset_p): Use arc_needs_pcl_p. ++ (arc_legitimate_pic_addr_p): Handle TLS unspecs. ++ (arc_raw_symbolic_reference_mentioned_p): Likewise. ++ (arc_get_tp, arc_emit_call_tls_get_addr): New function. ++ (arc_legitimize_tls_address): Likewise. ++ (DTPOFF_ZERO_SYM): Define. ++ (arc_legitimize_pic_address): Make it static, handle TLS cases. ++ (arc_output_pic_addr_const): Print TLS unspecs. ++ (prepare_pic_move): New function, replaces emit_pic_move. ++ (arc_legitimate_constant_p): Handle TLS unspecs. ++ (arc_legitimate_address_p): Likewise. ++ (arc_rewrite_small_data_p): Use assert for TLS constants. ++ (prepare_move_operands): Use prepare_pic_move. ++ (arc_legitimize_address): Legitimize tls addresses. ++ (arc_epilogue_uses): Check for arc_tp_regno. ++ (arc_eh_uses, insn_is_tls_gd_dispatch): New function. ++ * config/arc/arc.h [DEFAULT_LIBC != LIBC_UCLIBC] (EXTRA_SPECS): ++ Define. ++ [DEFAULT_LIBC != LIBC_UCLIBC] (ARC_TLS_EXTRA_START_SPEC): ++ Likewise. ++ [DEFAULT_LIBC != LIBC_UCLIBC] (STARTFILE_SPEC): Add ++ %(arc_tls_extra_start_spec). ++ (TARGET_CPU_CPP_BUILTINS): Define __ARC_TLS_REGNO__. ++ (REGNO_OK_FOR_BASE_P): Check for arc_tp_regno. ++ (EH_USES): Define. ++ (INSN_REFERENCES_ARE_DELAYED): Use insn_is_tls_gd_dispatch. ++ * config/arc/arc.md (UNSPEC_TLS_GD, UNSPEC_TLS_LD, UNSPEC_TLS_IE) ++ (UNSPEC_TLS_OFF): Add. ++ (R10_REG): Define. ++ (tls_load_tp_soft, tls_gd_load, tls_gd_get_addr, tls_gd_dispatch) ++ (get_thread_pointersi): New patterns. ++ * config/arc/arc.opt (mtp-regno): New option. ++ * config/arc/predicates.md (move_src_operand): Handle TLS symbols. ++ (move_dest_operand): Likewise. ++ * configure: Regenerate. ++ * configure.ac: Add arc*-*-* case to test for tls. ++ * doc/invoke.texi (ARC options): Document mtp-regno. ++ ++2016-04-28 Claudiu Zissulescu + + * config/arc/arc.c (arc_vector_mode_supported_p): Add support for + the new ARC HS SIMD instructions. +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index f487291d35d7..3bf28a088bd9 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -57,7 +57,6 @@ extern unsigned int arc_compute_frame_size (int); + extern bool arc_ccfsm_branch_deleted_p (void); + extern void arc_ccfsm_record_branch_deleted (void); + +-extern rtx arc_legitimize_pic_address (rtx, rtx); + void arc_asm_output_aligned_decl_local (FILE *, tree, const char *, + unsigned HOST_WIDE_INT, + unsigned HOST_WIDE_INT, +@@ -68,7 +67,6 @@ extern bool check_if_valid_sleep_operand (rtx *, int); + extern bool arc_legitimate_constant_p (machine_mode, rtx); + extern bool arc_legitimate_pc_offset_p (rtx); + extern bool arc_legitimate_pic_addr_p (rtx); +-extern void emit_pic_move (rtx *, machine_mode); + extern bool arc_raw_symbolic_reference_mentioned_p (rtx, bool); + extern bool arc_legitimate_pic_operand_p (rtx); + extern bool arc_is_longcall_p (rtx); +@@ -118,8 +116,10 @@ extern bool arc_text_label (rtx_insn *insn); + extern int arc_decl_pretend_args (tree decl); + extern bool arc_short_comparison_p (rtx, int); + extern bool arc_epilogue_uses (int regno); ++extern bool arc_eh_uses (int regno); + /* insn-attrtab.c doesn't include reload.h, which declares regno_clobbered_p. */ + extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode, int); + extern int arc_return_slot_offset (void); + extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int); + extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool); ++extern bool insn_is_tls_gd_dispatch (rtx_insn *); +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index d120946a5f2f..d40d54deb34a 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -217,7 +217,6 @@ static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int); + static int branch_dest (rtx); + + static void arc_output_pic_addr_const (FILE *, rtx, int); +-void emit_pic_move (rtx *, machine_mode); + bool arc_legitimate_pic_operand_p (rtx); + static bool arc_function_ok_for_sibcall (tree, tree); + static rtx arc_function_value (const_tree, const_tree, bool); +@@ -457,6 +456,11 @@ static void arc_finalize_pic (void); + #undef TARGET_ASM_ALIGNED_SI_OP + #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t" + ++#ifdef HAVE_AS_TLS ++#undef TARGET_HAVE_TLS ++#define TARGET_HAVE_TLS HAVE_AS_TLS ++#endif ++ + #undef TARGET_DWARF_REGISTER_SPAN + #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span + +@@ -1322,6 +1326,14 @@ arc_conditional_register_usage (void) + strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo"); + strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi"); + } ++ ++ /* The nature of arc_tp_regno is actually something more like a global ++ register, however globalize_reg requires a declaration. ++ We use EPILOGUE_USES to compensate so that sets from ++ __builtin_set_frame_pointer are not deleted. */ ++ if (arc_tp_regno != -1) ++ fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1; ++ + if (TARGET_MULMAC_32BY16_SET) + { + fix_start = 56; +@@ -3411,7 +3423,16 @@ arc_print_operand (FILE *file, rtx x, int code) + } + /* Fall through. Let output_addr_const deal with it. */ + default : +- if (flag_pic) ++ if (flag_pic ++ || (GET_CODE (x) == CONST ++ && GET_CODE (XEXP (x, 0)) == UNSPEC ++ && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF ++ || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD)) ++ || (GET_CODE (x) == CONST ++ && GET_CODE (XEXP (x, 0)) == PLUS ++ && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC ++ && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF ++ || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD))) + arc_output_pic_addr_const (file, x, code); + else + { +@@ -3476,6 +3497,17 @@ arc_print_operand_address (FILE *file , rtx addr) + { + rtx c = XEXP (addr, 0); + ++ if ((GET_CODE (c) == UNSPEC ++ && (XINT (c, 1) == UNSPEC_TLS_OFF ++ || XINT (c, 1) == UNSPEC_TLS_IE)) ++ || (GET_CODE (c) == PLUS ++ && GET_CODE (XEXP (c, 0)) == UNSPEC ++ && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF))) ++ { ++ arc_output_pic_addr_const (file, c, 0); ++ break; ++ } ++ gcc_assert (GET_CODE (c) == PLUS); + gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF); + gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT); + +@@ -4547,6 +4579,44 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code, + } + } + ++/* Helper used by arc_legitimate_pc_offset_p. */ ++ ++static bool ++arc_needs_pcl_p (rtx x) ++{ ++ register const char *fmt; ++ register int i, j; ++ ++ if ((GET_CODE (x) == UNSPEC) ++ && (XVECLEN (x, 0) == 1) ++ && (GET_CODE (XVECEXP (x, 0, 0)) == SYMBOL_REF)) ++ switch (XINT (x, 1)) ++ { ++ case ARC_UNSPEC_GOT: ++ case UNSPEC_TLS_GD: ++ case UNSPEC_TLS_IE: ++ return true; ++ default: ++ break; ++ } ++ ++ fmt = GET_RTX_FORMAT (GET_CODE (x)); ++ for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--) ++ { ++ if (fmt[i] == 'e') ++ { ++ if (arc_needs_pcl_p (XEXP (x, i))) ++ return true; ++ } ++ else if (fmt[i] == 'E') ++ for (j = XVECLEN (x, i) - 1; j >= 0; j--) ++ if (arc_needs_pcl_p (XVECEXP (x, i, j))) ++ return true; ++ } ++ ++ return false; ++} ++ + /* Return true if ADDR is an address that needs to be expressed as an + explicit sum of pcl + offset. */ + +@@ -4555,17 +4625,8 @@ arc_legitimate_pc_offset_p (rtx addr) + { + if (GET_CODE (addr) != CONST) + return false; +- addr = XEXP (addr, 0); +- if (GET_CODE (addr) == PLUS) +- { +- if (GET_CODE (XEXP (addr, 1)) != CONST_INT) +- return false; +- addr = XEXP (addr, 0); +- } +- return (GET_CODE (addr) == UNSPEC +- && XVECLEN (addr, 0) == 1 +- && XINT (addr, 1) == ARC_UNSPEC_GOT +- && GET_CODE (XVECEXP (addr, 0, 0)) == SYMBOL_REF); ++ ++ return arc_needs_pcl_p (addr); + } + + /* Return true if ADDR is a valid pic address. +@@ -4594,9 +4655,11 @@ arc_legitimate_pic_addr_p (rtx addr) + || XVECLEN (addr, 0) != 1) + return false; + +- /* Must be @GOT or @GOTOFF. */ ++ /* Must be one of @GOT, @GOTOFF, @tlsgd, tlsie. */ + if (XINT (addr, 1) != ARC_UNSPEC_GOT +- && XINT (addr, 1) != ARC_UNSPEC_GOTOFF) ++ && XINT (addr, 1) != ARC_UNSPEC_GOTOFF ++ && XINT (addr, 1) != UNSPEC_TLS_GD ++ && XINT (addr, 1) != UNSPEC_TLS_IE) + return false; + + if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF +@@ -4654,6 +4717,10 @@ arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local) + + if (GET_CODE (op) == SYMBOL_REF) + { ++ if (SYMBOL_REF_TLS_MODEL (op)) ++ return true; ++ if (!flag_pic) ++ return false; + tree decl = SYMBOL_REF_DECL (op); + return !skip_local || !decl || !default_binds_local_p (decl); + } +@@ -4680,11 +4747,114 @@ arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local) + return false; + } + ++/* Get the thread pointer. */ ++ ++static rtx ++arc_get_tp (void) ++{ ++ /* If arc_tp_regno has been set, we can use that hard register ++ directly as a base register. */ ++ if (arc_tp_regno != -1) ++ return gen_rtx_REG (Pmode, arc_tp_regno); ++ ++ /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid ++ conflicts with function arguments / results. */ ++ rtx reg = gen_reg_rtx (Pmode); ++ emit_insn (gen_tls_load_tp_soft ()); ++ emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG)); ++ return reg; ++} ++ ++/* Helper to be used by TLS Global dynamic model. */ ++ ++static rtx ++arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv) ++{ ++ rtx r0 = gen_rtx_REG (Pmode, R0_REG); ++ rtx insns; ++ rtx call_fusage = NULL_RTX; ++ ++ start_sequence (); ++ ++ rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), reloc); ++ x = gen_rtx_CONST (Pmode, x); ++ emit_move_insn (r0, x); ++ use_reg (&call_fusage, r0); ++ ++ gcc_assert (reloc == UNSPEC_TLS_GD); ++ rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym)); ++ /* Should we set RTL_CONST_CALL_P? We read memory, but not in a ++ way that the application should care. */ ++ RTL_PURE_CALL_P (call_insn) = 1; ++ add_function_usage_to (call_insn, call_fusage); ++ ++ insns = get_insns (); ++ end_sequence (); ++ ++ rtx dest = gen_reg_rtx (Pmode); ++ emit_libcall_block (insns, dest, r0, eqv); ++ return dest; ++} ++ ++#define DTPOFF_ZERO_SYM ".tdata" ++ ++/* Return a legitimized address for ADDR, ++ which is a SYMBOL_REF with tls_model MODEL. */ ++ ++static rtx ++arc_legitimize_tls_address (rtx addr, enum tls_model model) ++{ ++ if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC) ++ model = TLS_MODEL_LOCAL_EXEC; ++ ++ switch (model) ++ { ++ case TLS_MODEL_LOCAL_DYNAMIC: ++ rtx base; ++ tree decl; ++ const char *base_name; ++ rtvec v; ++ ++ decl = SYMBOL_REF_DECL (addr); ++ base_name = DTPOFF_ZERO_SYM; ++ if (decl && bss_initializer_p (decl)) ++ base_name = ".tbss"; ++ ++ base = gen_rtx_SYMBOL_REF (Pmode, base_name); ++ if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0) ++ { ++ if (!flag_pic) ++ goto local_exec; ++ v = gen_rtvec (1, addr); ++ } ++ else ++ v = gen_rtvec (2, addr, base); ++ addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF); ++ addr = gen_rtx_CONST (Pmode, addr); ++ base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC); ++ return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr); ++ case TLS_MODEL_GLOBAL_DYNAMIC: ++ return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr); ++ case TLS_MODEL_INITIAL_EXEC: ++ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_IE); ++ addr = gen_rtx_CONST (Pmode, addr); ++ addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr)); ++ return gen_rtx_PLUS (Pmode, arc_get_tp (), addr); ++ case TLS_MODEL_LOCAL_EXEC: ++ local_exec: ++ addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_OFF); ++ addr = gen_rtx_CONST (Pmode, addr); ++ return gen_rtx_PLUS (Pmode, arc_get_tp (), addr); ++ default: ++ gcc_unreachable (); ++ } ++} ++ + /* Legitimize a pic address reference in ORIG. + The return value is the legitimated address. + If OLDX is non-zero, it is the target to assign the address to first. */ + +-rtx ++static rtx + arc_legitimize_pic_address (rtx orig, rtx oldx) + { + rtx addr = orig; +@@ -4696,40 +4866,36 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + + if (GET_CODE (addr) == LABEL_REF) + ; /* Do nothing. */ +- else if (GET_CODE (addr) == SYMBOL_REF +- && (CONSTANT_POOL_ADDRESS_P (addr) +- || SYMBOL_REF_LOCAL_P (addr))) ++ else if (GET_CODE (addr) == SYMBOL_REF) + { +- /* This symbol may be referenced via a displacement from the PIC +- base address (@GOTOFF). */ +- +- /* FIXME: if we had a way to emit pc-relative adds that don't +- create a GOT entry, we could do without the use of the gp register. */ +- crtl->uses_pic_offset_table = 1; +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOTOFF); +- pat = gen_rtx_CONST (Pmode, pat); +- pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat); +- +- if (oldx == NULL) +- oldx = gen_reg_rtx (Pmode); +- +- if (oldx != 0) ++ enum tls_model model = SYMBOL_REF_TLS_MODEL (addr); ++ if (model != 0) ++ return arc_legitimize_tls_address (addr, model); ++ else if (!flag_pic) ++ return orig; ++ else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr)) + { +- emit_move_insn (oldx, pat); +- pat = oldx; ++ /* This symbol may be referenced via a displacement from the ++ PIC base address (@GOTOFF). */ ++ ++ /* FIXME: if we had a way to emit pc-relative adds that ++ don't create a GOT entry, we could do without the use of ++ the gp register. */ ++ crtl->uses_pic_offset_table = 1; ++ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOTOFF); ++ pat = gen_rtx_CONST (Pmode, pat); ++ pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat); ++ } ++ else ++ { ++ /* This symbol must be referenced via a load from the ++ Global Offset Table (@GOTPC). */ ++ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT); ++ pat = gen_rtx_CONST (Pmode, pat); ++ pat = gen_const_mem (Pmode, pat); + } + +- } +- else if (GET_CODE (addr) == SYMBOL_REF) +- { +- /* This symbol must be referenced via a load from the +- Global Offset Table (@GOTPC). */ +- +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT); +- pat = gen_rtx_CONST (Pmode, pat); +- pat = gen_const_mem (Pmode, pat); +- +- if (oldx == 0) ++ if (oldx == NULL) + oldx = gen_reg_rtx (Pmode); + + emit_move_insn (oldx, pat); +@@ -4752,45 +4918,23 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + { + rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1); + +- /* Check first to see if this is a constant offset from a @GOTOFF +- symbol reference. */ +- if ((GET_CODE (op0) == LABEL_REF +- || (GET_CODE (op0) == SYMBOL_REF +- && (CONSTANT_POOL_ADDRESS_P (op0) +- || SYMBOL_REF_LOCAL_P (op0)))) +- && GET_CODE (op1) == CONST_INT) +- { +- /* FIXME: like above, could do without gp reference. */ +- crtl->uses_pic_offset_table = 1; +- pat +- = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, op0), ARC_UNSPEC_GOTOFF); +- pat = gen_rtx_PLUS (Pmode, pat, op1); +- pat = gen_rtx_CONST (Pmode, pat); +- pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat); +- +- if (oldx != 0) +- { +- emit_move_insn (oldx, pat); +- pat = oldx; +- } +- } +- else +- { +- base = arc_legitimize_pic_address (XEXP (addr, 0), oldx); +- pat = arc_legitimize_pic_address (XEXP (addr, 1), ++ base = arc_legitimize_pic_address (op0, oldx); ++ pat = arc_legitimize_pic_address (op1, + base == oldx ? NULL_RTX : oldx); + +- if (GET_CODE (pat) == CONST_INT) +- pat = plus_constant (Pmode, base, INTVAL (pat)); +- else ++ if (base == op0 && pat == op1) ++ return orig; ++ ++ if (GET_CODE (pat) == CONST_INT) ++ pat = plus_constant (Pmode, base, INTVAL (pat)); ++ else ++ { ++ if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1))) + { +- if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1))) +- { +- base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0)); +- pat = XEXP (pat, 1); +- } +- pat = gen_rtx_PLUS (Pmode, base, pat); ++ base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0)); ++ pat = XEXP (pat, 1); + } ++ pat = gen_rtx_PLUS (Pmode, base, pat); + } + } + } +@@ -4906,26 +5050,47 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) + + + case UNSPEC: +- gcc_assert (XVECLEN (x, 0) == 1); +- if (XINT (x, 1) == ARC_UNSPEC_GOT) +- fputs ("pcl,", file); +- arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code); ++ const char *suffix; ++ bool pcrel; pcrel = false; ++ rtx base; base = NULL; ++ gcc_assert (XVECLEN (x, 0) >= 1); + switch (XINT (x, 1)) + { + case ARC_UNSPEC_GOT: +- fputs ("@gotpc", file); ++ suffix = "@gotpc", pcrel = true; + break; + case ARC_UNSPEC_GOTOFF: +- fputs ("@gotoff", file); ++ suffix = "@gotoff"; + break; + case ARC_UNSPEC_PLT: +- fputs ("@plt", file); ++ suffix = "@plt"; ++ break; ++ case UNSPEC_TLS_GD: ++ suffix = "@tlsgd", pcrel = true; ++ break; ++ case UNSPEC_TLS_IE: ++ suffix = "@tlsie", pcrel = true; ++ break; ++ case UNSPEC_TLS_OFF: ++ if (XVECLEN (x, 0) == 2) ++ base = XVECEXP (x, 0, 1); ++ if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC ++ || (!flag_pic && !base)) ++ suffix = "@tpoff"; ++ else ++ suffix = "@dtpoff"; + break; + default: + output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1)); + break; + } +- break; ++ if (pcrel) ++ fputs ("pcl,", file); ++ arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code); ++ fputs (suffix, file); ++ if (base) ++ arc_output_pic_addr_const (file, base, code); ++ break; + + default: + output_operand_lossage ("invalid expression as operand"); +@@ -4939,15 +5104,18 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) + + /* Emit insns to move operands[1] into operands[0]. */ + +-void +-emit_pic_move (rtx *operands, machine_mode) ++static void ++prepare_pic_move (rtx *operands, machine_mode) + { +- rtx temp = reload_in_progress ? operands[0] : gen_reg_rtx (Pmode); +- +- if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])) ++ if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1]) ++ && flag_pic) + operands[1] = force_reg (Pmode, operands[1]); + else +- operands[1] = arc_legitimize_pic_address (operands[1], temp); ++ { ++ rtx temp = (reload_in_progress ? operands[0] ++ : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX); ++ operands[1] = arc_legitimize_pic_address (operands[1], temp); ++ } + } + + +@@ -5149,9 +5317,12 @@ arc_legitimate_pic_operand_p (rtx x) + satisfies CONSTANT_P. */ + + bool +-arc_legitimate_constant_p (machine_mode, rtx x) ++arc_legitimate_constant_p (machine_mode mode, rtx x) + { +- if (!flag_pic) ++ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x)) ++ return false; ++ ++ if (!flag_pic && mode != Pmode) + return true; + + switch (GET_CODE (x)) +@@ -5161,7 +5332,9 @@ arc_legitimate_constant_p (machine_mode, rtx x) + + if (GET_CODE (x) == PLUS) + { +- if (GET_CODE (XEXP (x, 1)) != CONST_INT) ++ if (flag_pic ++ ? GET_CODE (XEXP (x, 1)) != CONST_INT ++ : !arc_legitimate_constant_p (mode, XEXP (x, 1))) + return false; + x = XEXP (x, 0); + } +@@ -5173,6 +5346,9 @@ arc_legitimate_constant_p (machine_mode, rtx x) + case ARC_UNSPEC_PLT: + case ARC_UNSPEC_GOTOFF: + case ARC_UNSPEC_GOT: ++ case UNSPEC_TLS_GD: ++ case UNSPEC_TLS_IE: ++ case UNSPEC_TLS_OFF: + case UNSPEC_PROF: + return true; + +@@ -5187,9 +5363,14 @@ arc_legitimate_constant_p (machine_mode, rtx x) + /* Return true. */ + break; + +- case LABEL_REF: + case SYMBOL_REF: +- return false; ++ if (SYMBOL_REF_TLS_MODEL (x)) ++ return false; ++ /* Fall through. */ ++ case LABEL_REF: ++ if (flag_pic) ++ return false; ++ /* Fall through. */ + + default: + break; +@@ -5212,12 +5393,29 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict) + return true; + if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x))) + return true; +- if ((GET_MODE_SIZE (mode) != 16) +- && (GET_CODE (x) == SYMBOL_REF +- || GET_CODE (x) == LABEL_REF +- || GET_CODE (x) == CONST)) ++ ++ /* When we compile for size avoid const (@sym + offset) ++ addresses. */ ++ if (!flag_pic && optimize_size && !reload_completed ++ && (GET_CODE (x) == CONST) ++ && (GET_CODE (XEXP (x, 0)) == PLUS) ++ && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF) ++ && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0 ++ && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0))) + { +- if (!flag_pic || arc_legitimate_pic_addr_p (x)) ++ rtx addend = XEXP (XEXP (x, 0), 1); ++ gcc_assert (CONST_INT_P (addend)); ++ HOST_WIDE_INT offset = INTVAL (addend); ++ ++ /* Allow addresses having a large offset to pass. Anyhow they ++ will end in a limm. */ ++ return !(offset > -1024 && offset < 1020); ++ } ++ ++ if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x)) ++ { ++ if (flag_pic ? arc_legitimate_pic_addr_p (x) ++ : arc_legitimate_constant_p (Pmode, x)) + return true; + } + if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC +@@ -6860,8 +7058,12 @@ arc_rewrite_small_data_p (const_rtx x) + x = XEXP (x, 0); + } + +- return (GET_CODE (x) == SYMBOL_REF +- && SYMBOL_REF_SMALL_P(x)); ++ if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x)) ++ { ++ gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0); ++ return true; ++ } ++ return false; + } + + /* If possible, rewrite OP so that it refers to small data using +@@ -7280,40 +7482,39 @@ prepare_move_operands (rtx *operands, machine_mode mode) + { + /* We used to do this only for MODE_INT Modes, but addresses to floating + point variables may well be in the small data section. */ +- if (1) ++ if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode)) ++ operands[0] = arc_rewrite_small_data (operands[0]); ++ ++ if (mode == SImode && SYMBOLIC_CONST (operands[1])) + { +- if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode)) +- operands[0] = arc_rewrite_small_data (operands[0]); +- else if (mode == SImode && flag_pic && SYMBOLIC_CONST (operands[1])) +- { +- emit_pic_move (operands, SImode); ++ prepare_pic_move (operands, SImode); + +- /* Disable any REG_EQUALs associated with the symref +- otherwise the optimization pass undoes the work done +- here and references the variable directly. */ +- } +- else if (GET_CODE (operands[0]) != MEM +- && !TARGET_NO_SDATA_SET +- && small_data_pattern (operands[1], Pmode)) +- { +- /* This is to take care of address calculations involving sdata +- variables. */ +- operands[1] = arc_rewrite_small_data (operands[1]); +- +- emit_insn (gen_rtx_SET (operands[0],operands[1])); +- /* ??? This note is useless, since it only restates the set itself. +- We should rather use the original SYMBOL_REF. However, there is +- the problem that we are lying to the compiler about these +- SYMBOL_REFs to start with. symbol@sda should be encoded specially +- so that we can tell it apart from an actual symbol. */ +- set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]); +- +- /* Take care of the REG_EQUAL note that will be attached to mark the +- output reg equal to the initial symbol_ref after this code is +- executed. */ +- emit_move_insn (operands[0], operands[0]); +- return true; +- } ++ /* Disable any REG_EQUALs associated with the symref ++ otherwise the optimization pass undoes the work done ++ here and references the variable directly. */ ++ } ++ ++ if (GET_CODE (operands[0]) != MEM ++ && !TARGET_NO_SDATA_SET ++ && small_data_pattern (operands[1], Pmode)) ++ { ++ /* This is to take care of address calculations involving sdata ++ variables. */ ++ operands[1] = arc_rewrite_small_data (operands[1]); ++ ++ emit_insn (gen_rtx_SET (operands[0],operands[1])); ++ /* ??? This note is useless, since it only restates the set itself. ++ We should rather use the original SYMBOL_REF. However, there is ++ the problem that we are lying to the compiler about these ++ SYMBOL_REFs to start with. symbol@sda should be encoded specially ++ so that we can tell it apart from an actual symbol. */ ++ set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]); ++ ++ /* Take care of the REG_EQUAL note that will be attached to mark the ++ output reg equal to the initial symbol_ref after this code is ++ executed. */ ++ emit_move_insn (operands[0], operands[0]); ++ return true; + } + + if (MEM_P (operands[0]) +@@ -8311,6 +8512,13 @@ arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED, + static rtx + arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode) + { ++ if (GET_CODE (orig_x) == SYMBOL_REF) ++ { ++ enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x); ++ if (model != 0) ++ return arc_legitimize_tls_address (orig_x, model); ++ } ++ + rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode); + + if (new_x) +@@ -9070,6 +9278,8 @@ arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee) + bool + arc_epilogue_uses (int regno) + { ++ if (regno == arc_tp_regno) ++ return true; + if (reload_completed) + { + if (ARC_INTERRUPT_P (cfun->machine->fn_type)) +@@ -9085,6 +9295,16 @@ arc_epilogue_uses (int regno) + return regno == arc_return_address_regs[arc_compute_function_type (cfun)]; + } + ++/* Helper for EH_USES macro. */ ++ ++bool ++arc_eh_uses (int regno) ++{ ++ if (regno == arc_tp_regno) ++ return true; ++ return false; ++} ++ + #ifndef TARGET_NO_LRA + #define TARGET_NO_LRA !TARGET_LRA + #endif +@@ -9590,6 +9810,13 @@ arc_dwarf_register_span (rtx rtl) + return p; + } + ++/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because ++ resource.h doesn't include the required header files. */ ++bool ++insn_is_tls_gd_dispatch (rtx_insn *insn) ++{ ++ return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch; ++} + + struct gcc_target targetm = TARGET_INITIALIZER; + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 5100a5b8f821..de6c6d11974a 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -109,6 +109,8 @@ along with GCC; see the file COPYING3. If not see + builtin_define ("__ARC_SIMD__"); \ + if (TARGET_BARREL_SHIFTER) \ + builtin_define ("__Xbarrel_shifter");\ ++ builtin_define_with_int_value ("__ARC_TLS_REGNO__", \ ++ arc_tp_regno); \ + builtin_assert ("cpu=arc"); \ + builtin_assert ("machine=arc"); \ + builtin_define (TARGET_BIG_ENDIAN \ +@@ -201,7 +203,13 @@ along with GCC; see the file COPYING3. If not see + #endif + + #if DEFAULT_LIBC != LIBC_UCLIBC +-#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti%O%s %{pg|p:crtg.o%s} crtbegin.o%s" ++#define ARC_TLS_EXTRA_START_SPEC "crttls.o%s" ++ ++#define EXTRA_SPECS \ ++ { "arc_tls_extra_start_spec", ARC_TLS_EXTRA_START_SPEC }, \ ++ ++#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti%O%s %{pg|p:crtg.o%s} " \ ++ "%(arc_tls_extra_start_spec) crtbegin.o%s" + #else + #define STARTFILE_SPEC "%{!shared:%{!mkernel:crt1.o%s}} crti.o%s \ + %{!shared:%{pg|p|profile:crtg.o%s} crtbegin.o%s} %{shared:crtbeginS.o%s}" +@@ -748,9 +756,10 @@ extern enum reg_class arc_regno_reg_class[]; + or a pseudo reg currently allocated to a suitable hard reg. + Since they use reg_renumber, they are safe only once reg_renumber + has been allocated, which happens in local-alloc.c. */ +-#define REGNO_OK_FOR_BASE_P(REGNO) \ +-((REGNO) < 29 || ((REGNO) == ARG_POINTER_REGNUM) || ((REGNO) == 63) ||\ +- (unsigned) reg_renumber[REGNO] < 29) ++#define REGNO_OK_FOR_BASE_P(REGNO) \ ++ ((REGNO) < 29 || ((REGNO) == ARG_POINTER_REGNUM) || ((REGNO) == 63) \ ++ || ((unsigned) reg_renumber[REGNO] < 29) \ ++ || ((unsigned) (REGNO) == (unsigned) arc_tp_regno)) + + #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) + +@@ -937,6 +946,8 @@ arc_return_addr_rtx(COUNT,FRAME) + + #define EPILOGUE_USES(REGNO) arc_epilogue_uses ((REGNO)) + ++#define EH_USES(REGNO) arc_eh_uses((REGNO)) ++ + /* Definitions for register eliminations. + + This is an array of structures. Each structure initializes one pair +@@ -1657,7 +1668,8 @@ extern enum arc_function_type arc_compute_function_type (struct function *); + && GET_CODE (PATTERN (X)) != CLOBBER \ + && (get_attr_type (X) == TYPE_CALL || get_attr_type (X) == TYPE_SFUNC)) + +-#define INSN_REFERENCES_ARE_DELAYED(insn) INSN_SETS_ARE_DELAYED (insn) ++#define INSN_REFERENCES_ARE_DELAYED(insn) \ ++ (INSN_SETS_ARE_DELAYED (insn) && !insn_is_tls_gd_dispatch (insn)) + + #define CALL_ATTR(X, NAME) \ + ((CALL_P (X) || NONJUMP_INSN_P (X)) \ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 4193d2610f19..4a7287b05365 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -111,6 +111,10 @@ + ARC_UNSPEC_PLT + ARC_UNSPEC_GOT + ARC_UNSPEC_GOTOFF ++ UNSPEC_TLS_GD ++ UNSPEC_TLS_LD ++ UNSPEC_TLS_IE ++ UNSPEC_TLS_OFF + UNSPEC_ARC_NORM + UNSPEC_ARC_NORMW + UNSPEC_ARC_SWAP +@@ -169,6 +173,7 @@ + (R1_REG 1) + (R2_REG 2) + (R3_REG 3) ++ (R10_REG 10) + (R12_REG 12) + (SP_REG 28) + (ILINK1_REGNUM 29) +@@ -5277,6 +5282,72 @@ + [(set_attr "type" "call") + (set_attr "is_SIBCALL" "yes")]) + ++(define_insn "tls_load_tp_soft" ++ [(set (reg:SI R0_REG) (unspec:SI [(const_int 0)] UNSPEC_TLS_OFF)) ++ (clobber (reg:SI RETURN_ADDR_REGNUM))] ++ "" ++ "*return arc_output_libcall (\"__read_tp\");" ++ [(set_attr "is_sfunc" "yes") ++ (set_attr "predicable" "yes")]) ++ ++(define_insn "tls_gd_load" ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c") ++ (unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c") ++ (match_operand:SI 2 "symbolic_operand" "X,X")] ++ UNSPEC_TLS_GD))] ++ "" ++ ".tls_gd_ld %2`ld%? %0,[%1]" ++ [(set_attr "type" "load") ++ ; if the linker has to patch this into IE, we need a long insn ++ ; (FIXME: or two short insn, ld_s / jl_s. missing -Os optimization.) ++ (set_attr_alternative "iscompact" ++ [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0)) ++ (const_string "*")] (const_string "maybe")) ++ (const_string "*")])]) ++ ++(define_insn "tls_gd_get_addr" ++ [(set (reg:SI R0_REG) ++ (call:SI (mem:SI (unspec:SI [(match_operand:SI 0 ++ "symbolic_operand" "X,X")] ++ UNSPEC_TLS_GD)) ++ (const_int 0))) ++ (clobber (reg:SI RETURN_ADDR_REGNUM))] ++ "" ++ ".tls_gd_ld %0`bl%* __tls_get_addr@plt" ++ [(set_attr "type" "call") ++ ; With TARGET_MEDIUM_CALLS, plt calls are not predicable. ++ (set_attr "predicable" "no")]) ++ ++; We make this call specific to the tls symbol to avoid commoning this ++; with calls for other symbols; we want the linker to be able to ++(define_insn "tls_gd_dispatch" ++ [(set (reg:SI R0_REG) ++ (unspec:SI ++ [(reg:SI R0_REG) ++ (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c")) ++ (const_int 0)) ++ (match_operand:SI 1 "symbolic_operand" "X,X,X")] ++ UNSPEC_TLS_GD)) ++ (clobber (reg:SI RETURN_ADDR_REGNUM)) ++ (clobber (reg:DI R10_REG)) ++ (clobber (reg:SI R12_REG))] ++ "" ++ ".tls_gd_call %1`jl%!%* [%0]" ++ [(set_attr "type" "call") ++ (set_attr "iscompact" "maybe,false,*") ++ (set_attr "predicable" "no,no,yes")]) ++ ++;; For thread pointer builtins ++(define_expand "get_thread_pointersi" ++ [(set (match_operand:SI 0 "register_operand") (match_dup 1))] ++ "" ++ "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);") ++ ++(define_expand "set_thread_pointersi" ++ [(set (match_dup 1) (match_operand:SI 0 "register_operand"))] ++ "" ++ "operands[1] = gen_rtx_REG (Pmode, arc_tp_regno);") ++ + ;; If hardware floating point is available, don't define a negdf pattern; + ;; it would be something like: + ;;(define_insn "negdf2" +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 2227b7554c30..76f66a2988b2 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -456,3 +456,10 @@ Enum(arc_fpu) String(fpus_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD) + + EnumValue + Enum(arc_fpu) String(fpud_all) Value(FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPU_DP | FPU_DC | FPU_DF | FPU_DD) ++ ++mtp-regno= ++Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25) ++Specify thread pointer register number ++ ++mtp-regno=none ++Target RejectNegative Var(arc_tp_regno,-1) +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 85bbf8435588..3c657c67f0d3 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -351,9 +351,12 @@ + switch (GET_CODE (op)) + { + case SYMBOL_REF : ++ if (SYMBOL_REF_TLS_MODEL (op)) ++ return 0; + case LABEL_REF : ++ return 1; + case CONST : +- return (!flag_pic || arc_legitimate_pic_operand_p(op)); ++ return arc_legitimate_constant_p (mode, op); + case CONST_INT : + return (LARGE_INT (INTVAL (op))); + case CONST_DOUBLE : +@@ -451,6 +454,16 @@ + && (GET_CODE (XEXP (addr, 1)) != PLUS + || !CONST_INT_P (XEXP (XEXP (addr, 1), 1)))) + return 0; ++ /* CONST_INT / CONST_DOUBLE is fine, but the PIC CONST ([..] UNSPEC)) ++ constructs are effectively indexed. */ ++ if (flag_pic) ++ { ++ rtx ad0 = addr; ++ while (GET_CODE (ad0) == PLUS) ++ ad0 = XEXP (ad0, 0); ++ if (GET_CODE (ad0) == CONST || GET_CODE (ad0) == UNSPEC) ++ return 0; ++ } + return address_operand (addr, mode); + } + default : +diff --git a/gcc/configure b/gcc/configure +index 954673c1c436..17ca349bdc3e 100755 +--- a/gcc/configure ++++ b/gcc/configure +@@ -23856,6 +23856,12 @@ foo: .long 25 + tls_first_minor=13 + tls_as_opt=--fatal-warnings + ;; ++ arc*-*-*) ++ conftest_s=' ++ add_s r0,r0, @foo@tpoff' ++ tls_first_major=2 ++ tls_first_minor=23 ++ ;; + cris-*-*|crisv32-*-*) + conftest_s=' + .section ".tdata","awT",@progbits +diff --git a/gcc/configure.ac b/gcc/configure.ac +index 4c65d441e72f..0a1e84f4f1f9 100644 +--- a/gcc/configure.ac ++++ b/gcc/configure.ac +@@ -3088,6 +3088,12 @@ foo: .long 25 + tls_first_minor=13 + tls_as_opt=--fatal-warnings + ;; ++ arc*-*-*) ++ conftest_s=' ++ add_s r0,r0, @foo@tpoff' ++ tls_first_major=2 ++ tls_first_minor=23 ++ ;; + cris-*-*|crisv32-*-*) + conftest_s=' + .section ".tdata","awT",@progbits +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 2ed92858e6c6..e6e725ec1c01 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -592,7 +592,7 @@ Objective-C and Objective-C++ Dialects}. + -mcrc -mdsp-packa -mdvbf -mlock -mmac-d16 -mmac-24 -mrtsc -mswape @gol + -mtelephony -mxy -misize -mannotate-align -marclinux -marclinux_prof @gol + -mlong-calls -mmedium-calls -msdata @gol +--mucb-mcount -mvolatile-cache @gol ++-mucb-mcount -mvolatile-cache -mtp-regno=@var{regno} @gol + -malign-call -mauto-modify-reg -mbbit-peephole -mno-brcc @gol + -mcase-vector-pcrel -mcompact-casesi -mno-cond-exec -mearly-cbranchsi @gol + -mexpand-adddi -mindexed-loads -mlra -mlra-priority-none @gol +@@ -13341,6 +13341,10 @@ Enable code density instructions for ARC EM, default on for ARC HS. + @opindex mll64 + Enable double load/store operations for ARC HS cores. + ++@item -mtp-regno=@var{regno} ++@opindex mtp-regno ++Specify thread pointer register number. ++ + @item -mmpy-option=@var{multo} + @opindex mmpy-option + Compile ARCv2 code with a multiplier design option. @samp{wlh1} is +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0004-ARC-Don-t-use-drsub-instructions-when-selecting-fpud.patch b/toolchain/gcc/patches/6.3.0/0004-ARC-Don-t-use-drsub-instructions-when-selecting-fpud.patch new file mode 100644 index 0000000..eb94e25 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0004-ARC-Don-t-use-drsub-instructions-when-selecting-fpud.patch @@ -0,0 +1,121 @@ +From 0a9f4daa9e9f009fb877f6de89aa3b6504cf2794 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 12:15:06 +0000 +Subject: [PATCH 04/89] [ARC] Don't use drsub* instructions when selecting + fpuda. + +The double precision floating point assist instructions are not +implementing the reverse double subtract instruction (drsub) found in +the FPX extension. + +gcc/ +2016-04-28 Claudiu Zissulescu + + * config/arc/arc.md (cpu_facility): Add fpx variant. + (subdf3): Prohibit use reverse sub when assist operations option + is enabled. + * config/arc/fpx.md (subdf3_insn, *dsubh_peep2_insn): Allow drsub + instructions only when FPX is enabled. + * testsuite/gcc.target/arc/trsub.c: New test. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235562 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 9 +++++++++ + gcc/config/arc/arc.md | 8 +++++++- + gcc/config/arc/fpx.md | 7 ++++--- + gcc/testsuite/gcc.target/arc/trsub.c | 10 ++++++++++ + 4 files changed, 30 insertions(+), 4 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/trsub.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 047bc20a9790..262cf2a4aa24 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,4 +1,13 @@ + 2016-04-28 Claudiu Zissulescu ++ ++ * config/arc/arc.md (cpu_facility): Add fpx variant. ++ (subdf3): Prohibit use reverse sub when assist operations option ++ is enabled. ++ * config/arc/fpx.md (subdf3_insn, *dsubh_peep2_insn): Allow drsub ++ instructions only when FPX is enabled. ++ * testsuite/gcc.target/arc/trsub.c: New test. ++ ++2016-04-28 Claudiu Zissulescu + Joern Rennecke + + * config/arc/arc-protos.h (arc_legitimize_pic_address): Remove +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 4a7287b05365..a58b491355a9 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -270,7 +270,7 @@ + - get_attr_length (insn)"))) + + ; for ARCv2 we need to disable/enable different instruction alternatives +-(define_attr "cpu_facility" "std,av1,av2" ++(define_attr "cpu_facility" "std,av1,av2,fpx" + (const_string "std")) + + ; We should consider all the instructions enabled until otherwise +@@ -282,6 +282,10 @@ + (and (eq_attr "cpu_facility" "av2") + (not (match_test "TARGET_V2"))) + (const_string "no") ++ ++ (and (eq_attr "cpu_facility" "fpx") ++ (match_test "TARGET_FP_DP_AX")) ++ (const_string "no") + ] + (const_string "yes"))) + +@@ -5780,6 +5784,8 @@ + " + if (TARGET_DPFP) + { ++ if (TARGET_FP_DP_AX && (GET_CODE (operands[1]) == CONST_DOUBLE)) ++ operands[1] = force_reg (DFmode, operands[1]); + if ((GET_CODE (operands[1]) == CONST_DOUBLE) + || GET_CODE (operands[2]) == CONST_DOUBLE) + { +diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md +index b79060037489..2e11157cabfb 100644 +--- a/gcc/config/arc/fpx.md ++++ b/gcc/config/arc/fpx.md +@@ -304,7 +304,8 @@ + drsubh%F0%F2 0,%H1,%L1 + drsubh%F0%F2 0,%3,%L1" + [(set_attr "type" "dpfp_addsub") +- (set_attr "length" "4,8,4,8")]) ++ (set_attr "length" "4,8,4,8") ++ (set_attr "cpu_facility" "*,*,fpx,fpx")]) + + ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; ;; Peephole for following conversion +@@ -613,5 +614,5 @@ + drsubh%F0%F2 %H6, %H1, %L1 + drsubh%F0%F2 %H6, %3, %L1" + [(set_attr "type" "dpfp_addsub") +- (set_attr "length" "4,8,4,8")] +-) ++ (set_attr "length" "4,8,4,8") ++ (set_attr "cpu_facility" "*,*,fpx,fpx")]) +diff --git a/gcc/testsuite/gcc.target/arc/trsub.c b/gcc/testsuite/gcc.target/arc/trsub.c +new file mode 100644 +index 000000000000..031935fdc8f5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/trsub.c +@@ -0,0 +1,10 @@ ++/* Tests if we generate rsub instructions when compiling using ++ floating point assist instructions. */ ++/* { dg-do compile } */ ++/* { dg-options "-mfpu=fpuda -mcpu=arcem" } */ ++ ++double foo (double a) ++{ ++ return ((double) 0.12 - a); ++} ++/* { dg-final { scan-assembler-not "drsub.*" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0005-ARC-Fix-FPX-FPUDA-code-gen-when-compiling-for-big-en.patch b/toolchain/gcc/patches/6.3.0/0005-ARC-Fix-FPX-FPUDA-code-gen-when-compiling-for-big-en.patch new file mode 100644 index 0000000..7ae674c --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0005-ARC-Fix-FPX-FPUDA-code-gen-when-compiling-for-big-en.patch @@ -0,0 +1,140 @@ +From e1c7cc8f21823d1bbe874912884c4b2cc7f4ba67 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 12:52:04 +0000 +Subject: [PATCH 05/89] [ARC] Fix FPX/FPUDA code gen when compiling for + big-endian. + +gcc/ +2016-04-28 Claudiu Zissulescu + + * config/arc/arc.c (arc_process_double_reg_moves): Fix for + big-endian compilation. + (arc_rtx_costs): Fix high/low naming. + * config/arc/arc.md (addf3): Likewise. + (subdf3): Likewise. + (muldf3): Likewise. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235567 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 8 ++++++++ + gcc/config/arc/arc.c | 21 ++++++++++++--------- + gcc/config/arc/arc.md | 18 +++++++++--------- + 3 files changed, 29 insertions(+), 18 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 262cf2a4aa24..153194efe9a1 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,13 @@ + 2016-04-28 Claudiu Zissulescu + ++ * config/arc/arc.c (arc_process_double_reg_moves): Fix for ++ big-endian compilation. ++ * config/arc/arc.md (addf3): Likewise. ++ (subdf3): Likewise. ++ (muldf3): Likewise. ++ ++2016-04-28 Claudiu Zissulescu ++ + * config/arc/arc.md (cpu_facility): Add fpx variant. + (subdf3): Prohibit use reverse sub when assist operations option + is enabled. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index d40d54deb34a..e7067374e465 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -4426,17 +4426,16 @@ arc_rtx_costs (rtx x, machine_mode mode, int outer_code, + + case CONST_DOUBLE: + { +- rtx high, low; ++ rtx first, second; + + if (TARGET_DPFP) + { + *total = COSTS_N_INSNS (1); + return true; + } +- /* FIXME: correct the order of high,low */ +- split_double (x, &high, &low); +- *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high)) +- + !SMALL_INT (INTVAL (low))); ++ split_double (x, &first, &second); ++ *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first)) ++ + !SMALL_INT (INTVAL (second))); + return true; + } + +@@ -8928,8 +8927,10 @@ arc_process_double_reg_moves (rtx *operands) + { + /* When we have 'mov D, r' or 'mov D, D' then get the target + register pair for use with LR insn. */ +- rtx destHigh = simplify_gen_subreg(SImode, dest, DFmode, 4); +- rtx destLow = simplify_gen_subreg(SImode, dest, DFmode, 0); ++ rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode, ++ TARGET_BIG_ENDIAN ? 0 : 4); ++ rtx destLow = simplify_gen_subreg (SImode, dest, DFmode, ++ TARGET_BIG_ENDIAN ? 4 : 0); + + /* Produce the two LR insns to get the high and low parts. */ + emit_insn (gen_rtx_SET (destHigh, +@@ -8946,8 +8947,10 @@ arc_process_double_reg_moves (rtx *operands) + { + /* When we have 'mov r, D' or 'mov D, D' and we have access to the + LR insn get the target register pair. */ +- rtx srcHigh = simplify_gen_subreg(SImode, src, DFmode, 4); +- rtx srcLow = simplify_gen_subreg(SImode, src, DFmode, 0); ++ rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode, ++ TARGET_BIG_ENDIAN ? 0 : 4); ++ rtx srcLow = simplify_gen_subreg (SImode, src, DFmode, ++ TARGET_BIG_ENDIAN ? 4 : 0); + + emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode, + gen_rtvec (3, dest, srcHigh, srcLow), +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index a58b491355a9..8ec0ce0427ba 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -5752,9 +5752,9 @@ + { + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { +- rtx high, low, tmp; +- split_double (operands[2], &low, &high); +- tmp = force_reg (SImode, high); ++ rtx first, second, tmp; ++ split_double (operands[2], &first, &second); ++ tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); + emit_insn (gen_adddf3_insn (operands[0], operands[1], + operands[2], tmp, const0_rtx)); + } +@@ -5789,10 +5789,10 @@ + if ((GET_CODE (operands[1]) == CONST_DOUBLE) + || GET_CODE (operands[2]) == CONST_DOUBLE) + { +- rtx high, low, tmp; ++ rtx first, second, tmp; + int const_index = ((GET_CODE (operands[1]) == CONST_DOUBLE) ? 1 : 2); +- split_double (operands[const_index], &low, &high); +- tmp = force_reg (SImode, high); ++ split_double (operands[const_index], &first, &second); ++ tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); + emit_insn (gen_subdf3_insn (operands[0], operands[1], + operands[2], tmp, const0_rtx)); + } +@@ -5824,9 +5824,9 @@ + { + if (GET_CODE (operands[2]) == CONST_DOUBLE) + { +- rtx high, low, tmp; +- split_double (operands[2], &low, &high); +- tmp = force_reg (SImode, high); ++ rtx first, second, tmp; ++ split_double (operands[2], &first, &second); ++ tmp = force_reg (SImode, TARGET_BIG_ENDIAN ? first : second); + emit_insn (gen_muldf3_insn (operands[0], operands[1], + operands[2], tmp, const0_rtx)); + } +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0006-ARC-Pass-mfpuda-to-assembler.patch b/toolchain/gcc/patches/6.3.0/0006-ARC-Pass-mfpuda-to-assembler.patch new file mode 100644 index 0000000..f029a70 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0006-ARC-Pass-mfpuda-to-assembler.patch @@ -0,0 +1,46 @@ +From 77f712be933a5dd0c93acf6c1e1f43757f8e893a Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 28 Apr 2016 13:08:01 +0000 +Subject: [PATCH 06/89] [ARC] Pass mfpuda to assembler. + +gcc/ +2016-04-28 Claudiu Zissulescu + + * config/arc/arc.h (ASM_SPEC): Pass mfpuda to assembler. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235568 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 4 ++++ + gcc/config/arc/arc.h | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 153194efe9a1..4bc68957046f 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,9 @@ + 2016-04-28 Claudiu Zissulescu + ++ * config/arc/arc.h (ASM_SPEC): Pass mfpuda to assembler. ++ ++2016-04-28 Claudiu Zissulescu ++ + * config/arc/arc.c (arc_process_double_reg_moves): Fix for + big-endian compilation. + * config/arc/arc.md (addf3): Likewise. +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index de6c6d11974a..37c1afa6712e 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -155,7 +155,7 @@ along with GCC; see the file COPYING3. If not see + %{mcpu=ARC700:-mEA} \ + %{!mcpu=*:" ASM_DEFAULT "} \ + %{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \ +-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} \ ++%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \ + %{msimd} \ + %{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \ + %{mcpu=ARC700|!mcpu=*:%{mlock}} \ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0007-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0007-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch new file mode 100644 index 0000000..4016f8e --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0007-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch @@ -0,0 +1,128 @@ +From 820d3306c7dd9ce68463f16050cae1edf8bdcc83 Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 16:59:18 +0000 +Subject: [PATCH 07/89] 2016-04-28 Andrew Burgess + + + * common/config/arc/arc-common.c (arc_handle_option): Add NPS400 + support, setup defaults. + * config/arc/arc-opts.h (enum processor_type): Add NPS400. + * config/arc/arc.c (arc_init): Add NPS400 support. + * config/arc/arc.h (CPP_SPEC): Add NPS400 defines. + (TARGET_ARC700): NPS400 is also an ARC700. + * config/arc/arc.opt: Add NPS400 options to -mcpu=. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235584 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 10 ++++++++++ + gcc/common/config/arc/arc-common.c | 4 ++++ + gcc/config/arc/arc-opts.h | 1 + + gcc/config/arc/arc.c | 5 +++++ + gcc/config/arc/arc.h | 5 ++++- + gcc/config/arc/arc.opt | 6 ++++++ + 6 files changed, 30 insertions(+), 1 deletion(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 4bc68957046f..f5d047e5fe64 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,13 @@ ++2016-04-28 Andrew Burgess ++ ++ * common/config/arc/arc-common.c (arc_handle_option): Add NPS400 ++ support, setup defaults. ++ * config/arc/arc-opts.h (enum processor_type): Add NPS400. ++ * config/arc/arc.c (arc_init): Add NPS400 support. ++ * config/arc/arc.h (CPP_SPEC): Add NPS400 defines. ++ (TARGET_ARC700): NPS400 is also an ARC700. ++ * config/arc/arc.opt: Add NPS400 options to -mcpu=. ++ + 2016-04-28 Claudiu Zissulescu + + * config/arc/arc.h (ASM_SPEC): Pass mfpuda to assembler. +diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c +index 64fb053142c9..f5b9c6d3cc98 100644 +--- a/gcc/common/config/arc/arc-common.c ++++ b/gcc/common/config/arc/arc-common.c +@@ -83,6 +83,10 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, + + switch (value) + { ++ case PROCESSOR_NPS400: ++ if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) ) ++ opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1; ++ /* Fall through */ + case PROCESSOR_ARC600: + case PROCESSOR_ARC700: + if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) ) +diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h +index 1e11ebc41ffb..cbd78985dd8b 100644 +--- a/gcc/config/arc/arc-opts.h ++++ b/gcc/config/arc/arc-opts.h +@@ -24,6 +24,7 @@ enum processor_type + PROCESSOR_ARC600, + PROCESSOR_ARC601, + PROCESSOR_ARC700, ++ PROCESSOR_NPS400, + PROCESSOR_ARCEM, + PROCESSOR_ARCHS + }; +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index e7067374e465..e3744b8c971e 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -690,6 +690,11 @@ arc_init (void) + tune_dflt = TUNE_ARC700_4_2_STD; + break; + ++ case PROCESSOR_NPS400: ++ arc_cpu_string = "NPS400"; ++ tune_dflt = TUNE_ARC700_4_2_STD; ++ break; ++ + case PROCESSOR_ARCEM: + arc_cpu_string = "EM"; + break; +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 37c1afa6712e..b14352c3e262 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -138,6 +138,8 @@ along with GCC; see the file COPYING3. If not see + %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \ + %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \ + %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \ ++%{mcpu=NPS400:-D__NPS400__} \ ++%{mcpu=nps400:-D__NPS400__} \ + " + + #define CC1_SPEC "\ +@@ -305,7 +307,8 @@ along with GCC; see the file COPYING3. If not see + + #define TARGET_ARC600 (arc_cpu == PROCESSOR_ARC600) + #define TARGET_ARC601 (arc_cpu == PROCESSOR_ARC601) +-#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700) ++#define TARGET_ARC700 (arc_cpu == PROCESSOR_ARC700 \ ++ || arc_cpu == PROCESSOR_NPS400) + #define TARGET_EM (arc_cpu == PROCESSOR_ARCEM) + #define TARGET_HS (arc_cpu == PROCESSOR_ARCHS) + #define TARGET_V2 \ +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 76f66a2988b2..45bb6a6167d3 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -189,6 +189,12 @@ EnumValue + Enum(processor_type) String(arc700) Value(PROCESSOR_ARC700) + + EnumValue ++Enum(processor_type) String(nps400) Value(PROCESSOR_NPS400) ++ ++EnumValue ++Enum(processor_type) String(NPS400) Value(PROCESSOR_NPS400) ++ ++EnumValue + Enum(processor_type) String(ARCEM) Value(PROCESSOR_ARCEM) + + EnumValue +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0008-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0008-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch new file mode 100644 index 0000000..1657dbb --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0008-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch @@ -0,0 +1,78 @@ +From aaa5e66450e85915f9190176a8f2fcb453d6bca4 Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 17:16:05 +0000 +Subject: [PATCH 08/89] 2016-04-28 Andrew Burgess + + + * config/arc/constraints.md (Usd): Convert to define_constraint. + (Us<): Likewise. + (Us>): Likewise. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235587 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 6 ++++++ + gcc/config/arc/constraints.md | 18 +++++++++++------- + 2 files changed, 17 insertions(+), 7 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index f5d047e5fe64..8a90a7836e43 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,11 @@ + 2016-04-28 Andrew Burgess + ++ * config/arc/constraints.md (Usd): Convert to define_constraint. ++ (Us<): Likewise. ++ (Us>): Likewise. ++ ++2016-04-28 Andrew Burgess ++ + * common/config/arc/arc-common.c (arc_handle_option): Add NPS400 + support, setup defaults. + * config/arc/arc-opts.h (enum processor_type): Add NPS400. +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index 668b60a6b3a6..b6954ad9456a 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -269,11 +269,15 @@ + (and (match_code "mem") + (match_test "compact_store_memory_operand (op, VOIDmode)"))) + +-(define_memory_constraint "Usd" +- "@internal +- A valid _small-data_ memory operand for ARCompact instructions" +- (and (match_code "mem") +- (match_test "compact_sda_memory_operand (op, VOIDmode)"))) ++; Don't use define_memory_constraint here as the relocation patching ++; for small data symbols only works within a ld/st instruction and ++; define_memory_constraint may result in the address being calculated ++; into a register first. ++(define_constraint "Usd" ++ "@internal ++ A valid _small-data_ memory operand for ARCompact instructions" ++ (and (match_code "mem") ++ (match_test "compact_sda_memory_operand (op, VOIDmode)"))) + + (define_memory_constraint "Usc" + "@internal +@@ -283,7 +287,7 @@ + ;; ??? the assembler rejects stores of immediates to small data. + (match_test "!compact_sda_memory_operand (op, VOIDmode)"))) + +-(define_memory_constraint "Us<" ++(define_constraint "Us<" + "@internal + Stack pre-decrement" + (and (match_code "mem") +@@ -291,7 +295,7 @@ + (match_test "REG_P (XEXP (XEXP (op, 0), 0))") + (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))) + +-(define_memory_constraint "Us>" ++(define_constraint "Us>" + "@internal + Stack post-increment" + (and (match_code "mem") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0009-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0009-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch new file mode 100644 index 0000000..c8ae0c2 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0009-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch @@ -0,0 +1,701 @@ +From d23300e56230f917866761c4d6502a578d7abeec Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 18:21:42 +0000 +Subject: [PATCH 09/89] 2016-04-28 Joern Rennecke + Andrew Burgess + gcc: * config/arc/arc.h + (SYMBOL_FLAG_CMEM): Define. (TARGET_NPS_CMEM_DEFAULT): Provide + default definition. * config/arc/arc.c (arc_address_cost): Return 0 + for cmem_address. (arc_encode_section_info): Set SYMBOL_FLAG_CMEM + where indicated. * config/arc/arc.opt (mcmem): New option. * + config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative, supply + length for r/m alternative. (*extendqisi2_ac): Likewise. + (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and + r/Uex alternative. (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives. + (movhi_insn): Likewise. (movsi_insn): Add r/Ucm,Ucm/w + alternatives. (*zero_extendqihi2_i): Add r/Ucm alternative. + (*zero_extendqisi2_ac): Likewise. (*zero_extendhisi2_i): Likewise. + * config/arc/constraints.md (Uex): New memory constraint. (Ucm): + New define_constraint. * config/arc/predicates.md + (long_immediate_loadstore_operand): Return 0 for MEM with + cmem_address address. (cmem_address_0): New predicates. + (cmem_address_1): Likewise. (cmem_address_2): Likewise. + (cmem_address): Likewise. gcc/testsuite: * gcc.target/arc/cmem-1.c: + New file. * gcc.target/arc/cmem-2.c: New file. * + gcc.target/arc/cmem-3.c: New file. * gcc.target/arc/cmem-4.c: New + file. * gcc.target/arc/cmem-5.c: New file. * + gcc.target/arc/cmem-6.c: New file. * gcc.target/arc/cmem-7.c: New + file. * gcc.target/arc/cmem-ld.inc: New file. * + gcc.target/arc/cmem-st.inc: New file. + +--- + gcc/ChangeLog | 35 ++++++++++ + gcc/config/arc/arc.c | 20 ++++++ + gcc/config/arc/arc.h | 9 +++ + gcc/config/arc/arc.md | 115 +++++++++++++++++-------------- + gcc/config/arc/arc.opt | 8 +++ + gcc/config/arc/constraints.md | 14 +++- + gcc/config/arc/predicates.md | 19 +++++ + gcc/testsuite/ChangeLog | 13 ++++ + gcc/testsuite/gcc.target/arc/cmem-1.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-2.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-3.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-4.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-5.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-6.c | 10 +++ + gcc/testsuite/gcc.target/arc/cmem-7.c | 26 +++++++ + gcc/testsuite/gcc.target/arc/cmem-ld.inc | 16 +++++ + gcc/testsuite/gcc.target/arc/cmem-st.inc | 18 +++++ + 17 files changed, 302 insertions(+), 51 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-3.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-4.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-5.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-6.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-7.c + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-ld.inc + create mode 100644 gcc/testsuite/gcc.target/arc/cmem-st.inc + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 8a90a7836e43..f0d877721dd3 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,38 @@ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ ++ * config/arc/constraints.md (Usd): Convert to define_constraint. ++ (Us<): Likewise. ++ (Us>): Likewise. ++ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ ++ * config/arc/arc.h (SYMBOL_FLAG_CMEM): Define. ++ (TARGET_NPS_CMEM_DEFAULT): Provide default definition. ++ * config/arc/arc.c (arc_address_cost): Return 0 for cmem_address. ++ (arc_encode_section_info): Set SYMBOL_FLAG_CMEM where indicated. ++ * config/arc/arc.opt (mcmem): New option. ++ * config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative, ++ supply length for r/m alternative. ++ (*extendqisi2_ac): Likewise. ++ (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and ++ r/Uex alternative. ++ (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives. ++ (movhi_insn): Likewise. ++ (movsi_insn): Add r/Ucm,Ucm/w alternatives. ++ (*zero_extendqihi2_i): Add r/Ucm alternative. ++ (*zero_extendqisi2_ac): Likewise. ++ (*zero_extendhisi2_i): Likewise. ++ * config/arc/constraints.md (Uex): New memory constraint. ++ (Ucm): New define_constraint. ++ * config/arc/predicates.md (long_immediate_loadstore_operand): ++ Return 0 for MEM with cmem_address address. ++ (cmem_address_0): New predicates. ++ (cmem_address_1): Likewise. ++ (cmem_address_2): Likewise. ++ (cmem_address): Likewise. ++ + 2016-04-28 Andrew Burgess + + * config/arc/constraints.md (Usd): Convert to define_constraint. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index e3744b8c971e..ca9d31ceee95 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1843,6 +1843,8 @@ arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed) + case LABEL_REF : + case SYMBOL_REF : + case CONST : ++ if (TARGET_NPS_CMEM && cmem_address (addr, SImode)) ++ return 0; + /* Most likely needs a LIMM. */ + return COSTS_N_INSNS (1); + +@@ -4337,6 +4339,24 @@ arc_encode_section_info (tree decl, rtx rtl, int first) + + SYMBOL_REF_FLAGS (symbol) = flags; + } ++ else if (TREE_CODE (decl) == VAR_DECL) ++ { ++ rtx symbol = XEXP (rtl, 0); ++ ++ tree attr = (TREE_TYPE (decl) != error_mark_node ++ ? DECL_ATTRIBUTES (decl) : NULL_TREE); ++ ++ tree sec_attr = lookup_attribute ("section", attr); ++ if (sec_attr) ++ { ++ const char *sec_name ++ = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr))); ++ if (strcmp (sec_name, ".cmem") == 0 ++ || strcmp (sec_name, ".cmem_shared") == 0 ++ || strcmp (sec_name, ".cmem_private") == 0) ++ SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM; ++ } ++ } + } + + /* This is how to output a definition of an internal numbered label where +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index b14352c3e262..a17d41092507 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see + #define SYMBOL_FLAG_SHORT_CALL (SYMBOL_FLAG_MACH_DEP << 0) + #define SYMBOL_FLAG_MEDIUM_CALL (SYMBOL_FLAG_MACH_DEP << 1) + #define SYMBOL_FLAG_LONG_CALL (SYMBOL_FLAG_MACH_DEP << 2) ++#define SYMBOL_FLAG_CMEM (SYMBOL_FLAG_MACH_DEP << 3) + + /* Check if this symbol has a long_call attribute in its declaration */ + #define SYMBOL_REF_LONG_CALL_P(X) \ +@@ -321,6 +322,14 @@ along with GCC; see the file COPYING3. If not see + #define MULTILIB_DEFAULTS { "mARC700" } + #endif + ++#ifndef UNALIGNED_ACCESS_DEFAULT ++#define UNALIGNED_ACCESS_DEFAULT 0 ++#endif ++ ++#ifndef TARGET_NPS_CMEM_DEFAULT ++#define TARGET_NPS_CMEM_DEFAULT 0 ++#endif ++ + /* Target machine storage layout. */ + + /* We want zero_extract to mean the same +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 8ec0ce0427ba..93a2cad7dfa6 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -620,8 +620,8 @@ + ; The iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + (define_insn "*movqi_insn" +- [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w, w,Rcq,S,!*x,r,m,???m") +- (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,m,c,?Rac"))] ++ [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m") ++ (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] + "register_operand (operands[0], QImode) + || register_operand (operands[1], QImode)" + "@ +@@ -635,13 +635,15 @@ + ldb%? %0,%1%& + stb%? %1,%0%& + ldb%? %0,%1%& ++ xldb%U1 %0,%1 + ldb%U1%V1 %0,%1 ++ xstb%U0 %1,%0 + stb%U0%V0 %1,%0 + stb%U0%V0 %1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false") +- (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")]) + + (define_expand "movhi" + [(set (match_operand:HI 0 "move_dest_operand" "") +@@ -650,8 +652,8 @@ + "if (prepare_move_operands (operands, HImode)) DONE;") + + (define_insn "*movhi_insn" +- [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w,???w,Rcq#q,w,Rcq,S,r,m,???m,VUsc") +- (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac, ?i,?i,T,Rcq,m,c,?Rac,i"))] ++ [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc") ++ (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))] + "register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || (CONSTANT_P (operands[1]) +@@ -670,14 +672,16 @@ + mov%? %0,%S1 + ld%_%? %0,%1%& + st%_%? %1,%0%& ++ xld%_%U1 %0,%1 + ld%_%U1%V1 %0,%1 ++ xst%_%U0 %1,%0 + st%_%U0%V0 %1,%0 + st%_%U0%V0 %1,%0 + st%_%U0%V0 %S1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false") +- (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + + (define_expand "movsi" + [(set (match_operand:SI 0 "move_dest_operand" "") +@@ -696,8 +700,8 @@ + ; insns it should lengthen the return insn. + ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . + (define_insn "*movsi_insn" +- [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,m,???m,VUsc") +- (match_operand:SI 1 "move_src_operand" " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,m,c,?Rac,C32"))] ++ [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") ++ (match_operand:SI 1 "move_src_operand" " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || (CONSTANT_P (operands[1]) +@@ -722,17 +726,19 @@ + * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); + * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); + ld%? %0,%1%& ;15 +- ld%U1%V1 %0,%1 ;16 +- st%U0%V0 %1,%0 ;17 +- st%U0%V0 %1,%0 ;18 +- st%U0%V0 %S1,%0 ;19" +- [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false") ++ xld%U1 %0,%1 ;16 ++ ld%U1%V1 %0,%1 ;17 ++ xst%U0 %1,%0 ;18 ++ st%U0%V0 %1,%0 ;19 ++ st%U0%V0 %1,%0 ;20 ++ st%U0%V0 %S1,%0 ;21" ++ [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") + ; Use default length for iscompact to allow for COND_EXEC. But set length + ; of Crr to 4. +- (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,*,*,*,8") +- (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") ++ (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + + ;; Sometimes generated by the epilogue code. We don't want to + ;; recognize these addresses in general, because the limm is costly, +@@ -1459,18 +1465,19 @@ + + + (define_insn "*zero_extendqihi2_i" +- [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r") +- (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,m")))] ++ [(set (match_operand:HI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,r,r") ++ (zero_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,Ucm,m")))] + "" + "@ + extb%? %0,%1%& + extb%? %0,%1%& + bmsk%? %0,%1,7 + extb %0,%1 ++ xldb%U1 %0,%1 + ldb%U1 %0,%1" +- [(set_attr "type" "unary,unary,unary,unary,load") +- (set_attr "iscompact" "maybe,true,false,false,false") +- (set_attr "predicable" "no,no,yes,no,no")]) ++ [(set_attr "type" "unary,unary,unary,unary,load,load") ++ (set_attr "iscompact" "maybe,true,false,false,false,false") ++ (set_attr "predicable" "no,no,yes,no,no,no")]) + + (define_expand "zero_extendqihi2" + [(set (match_operand:HI 0 "dest_reg_operand" "") +@@ -1480,8 +1487,8 @@ + ) + + (define_insn "*zero_extendqisi2_ac" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r") +- (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,m")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,Rcq#q,Rcw,w,qRcq,!*x,r,r") ++ (zero_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "0,Rcq#q,0,c,T,Usd,Ucm,m")))] + "" + "@ + extb%? %0,%1%& +@@ -1490,10 +1497,11 @@ + extb %0,%1 + ldb%? %0,%1%& + ldb%? %0,%1%& ++ xldb%U1 %0,%1 + ldb%U1 %0,%1" +- [(set_attr "type" "unary,unary,unary,unary,load,load,load") +- (set_attr "iscompact" "maybe,true,false,false,true,true,false") +- (set_attr "predicable" "no,no,yes,no,no,no,no")]) ++ [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") ++ (set_attr "iscompact" "maybe,true,false,false,true,true,false,false") ++ (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) + + (define_expand "zero_extendqisi2" + [(set (match_operand:SI 0 "dest_reg_operand" "") +@@ -1503,8 +1511,8 @@ + ) + + (define_insn "*zero_extendhisi2_i" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r") +- (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,m")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq,q,Rcw,w,!x,Rcqq,r,r") ++ (zero_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "0,q,0,c,Usd,Usd,Ucm,m")))] + "" + "@ + ext%_%? %0,%1%& +@@ -1513,10 +1521,11 @@ + ext%_ %0,%1 + ld%_%? %0,%1%& + ld%_%U1 %0,%1 ++ * return TARGET_EM ? \"xldh%U1%V1 %0,%1\" : \"xldw%U1 %0,%1\"; + ld%_%U1%V1 %0,%1" +- [(set_attr "type" "unary,unary,unary,unary,load,load,load") +- (set_attr "iscompact" "maybe,true,false,false,true,false,false") +- (set_attr "predicable" "no,no,yes,no,no,no,no")]) ++ [(set_attr "type" "unary,unary,unary,unary,load,load,load,load") ++ (set_attr "iscompact" "maybe,true,false,false,true,false,false,false") ++ (set_attr "predicable" "no,no,yes,no,no,no,no,no")]) + + + (define_expand "zero_extendhisi2" +@@ -1529,15 +1538,17 @@ + ;; Sign extension instructions. + + (define_insn "*extendqihi2_i" +- [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r") +- (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,m")))] ++ [(set (match_operand:HI 0 "dest_reg_operand" "=Rcqq,r,r,r") ++ (sign_extend:HI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,r,Uex,m")))] + "" + "@ + sexb%? %0,%1%& + sexb %0,%1 ++ ldb.x%U1 %0,%1 + ldb.x%U1 %0,%1" +- [(set_attr "type" "unary,unary,load") +- (set_attr "iscompact" "true,false,false")]) ++ [(set_attr "type" "unary,unary,load,load") ++ (set_attr "iscompact" "true,false,false,false") ++ (set_attr "length" "*,*,*,8")]) + + + (define_expand "extendqihi2" +@@ -1548,15 +1559,17 @@ + ) + + (define_insn "*extendqisi2_ac" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r") +- (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") ++ (sign_extend:SI (match_operand:QI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] + "" + "@ + sexb%? %0,%1%& + sexb %0,%1 ++ ldb.x%U1 %0,%1 + ldb.x%U1 %0,%1" +- [(set_attr "type" "unary,unary,load") +- (set_attr "iscompact" "true,false,false")]) ++ [(set_attr "type" "unary,unary,load,load") ++ (set_attr "iscompact" "true,false,false,false") ++ (set_attr "length" "*,*,*,8")]) + + (define_expand "extendqisi2" + [(set (match_operand:SI 0 "dest_reg_operand" "") +@@ -1566,15 +1579,17 @@ + ) + + (define_insn "*extendhisi2_i" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r") +- (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,m")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") ++ (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] + "" + "@ + sex%_%? %0,%1%& + sex%_ %0,%1 ++ ld%_.x%U1%V1 %0,%1 + ld%_.x%U1%V1 %0,%1" +- [(set_attr "type" "unary,unary,load") +- (set_attr "iscompact" "true,false,false")]) ++ [(set_attr "type" "unary,unary,load,load") ++ (set_attr "iscompact" "true,false,false,false") ++ (set_attr "length" "*,*,4,8")]) + + (define_expand "extendhisi2" + [(set (match_operand:SI 0 "dest_reg_operand" "") +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 45bb6a6167d3..b2c7b3763c1d 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -469,3 +469,11 @@ Specify thread pointer register number + + mtp-regno=none + Target RejectNegative Var(arc_tp_regno,-1) ++ ++mcmem ++Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT) ++Enable use of NPS400 xld/xst extension. ++ ++munaligned-access ++Target Report Var(unaligned_access) Init(UNALIGNED_ACCESS_DEFAULT) ++Enable unaligned word and halfword accesses to packed data. +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index b6954ad9456a..c2992c9e9473 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -269,6 +269,13 @@ + (and (match_code "mem") + (match_test "compact_store_memory_operand (op, VOIDmode)"))) + ++(define_memory_constraint "Uex" ++ "@internal ++ A valid memory operand for limm-free extend instructions" ++ (and (match_code "mem") ++ (match_test "!cmem_address (XEXP (op, 0), SImode)") ++ (not (match_operand 0 "long_immediate_loadstore_operand")))) ++ + ; Don't use define_memory_constraint here as the relocation patching + ; for small data symbols only works within a ld/st instruction and + ; define_memory_constraint may result in the address being calculated +@@ -303,6 +310,12 @@ + (match_test "REG_P (XEXP (XEXP (op, 0), 0))") + (match_test "REGNO (XEXP (XEXP (op, 0), 0)) == SP_REG"))) + ++(define_constraint "Ucm" ++ "@internal ++ cmem access" ++ (and (match_code "mem") ++ (match_test "TARGET_NPS_CMEM && cmem_address (XEXP (op, 0), VOIDmode)"))) ++ + ;; General constraints + + (define_constraint "Cbr" +@@ -430,4 +443,3 @@ + (define_memory_constraint "ATO" + "A memory with only a base register" + (match_operand 0 "mem_noofs_operand")) +- +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 3c657c67f0d3..0d2e217bf9d6 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -123,6 +123,8 @@ + int size = GET_MODE_SIZE (GET_MODE (op)); + + op = XEXP (op, 0); ++ if (TARGET_NPS_CMEM && cmem_address (op, SImode)) ++ return 0; + switch (GET_CODE (op)) + { + case SYMBOL_REF : +@@ -819,3 +821,20 @@ + (define_predicate "double_register_operand" + (ior (match_test "even_register_operand (op, mode)") + (match_test "arc_double_register_operand (op, mode)"))) ++ ++(define_predicate "cmem_address_0" ++ (and (match_code "symbol_ref") ++ (match_test "SYMBOL_REF_FLAGS (op) & SYMBOL_FLAG_CMEM"))) ++ ++(define_predicate "cmem_address_1" ++ (and (match_code "plus") ++ (match_test "cmem_address_0 (XEXP (op, 0), SImode)"))) ++ ++(define_predicate "cmem_address_2" ++ (and (match_code "const") ++ (match_test "cmem_address_1 (XEXP (op, 0), SImode)"))) ++ ++(define_predicate "cmem_address" ++ (ior (match_operand:SI 0 "cmem_address_0") ++ (match_operand:SI 0 "cmem_address_1") ++ (match_operand:SI 0 "cmem_address_2"))) +diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog +index d3c6533df2f2..63a13b84ee10 100644 +--- a/gcc/testsuite/ChangeLog ++++ b/gcc/testsuite/ChangeLog +@@ -1,3 +1,16 @@ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ ++ * gcc.target/arc/cmem-1.c: New file. ++ * gcc.target/arc/cmem-2.c: New file. ++ * gcc.target/arc/cmem-3.c: New file. ++ * gcc.target/arc/cmem-4.c: New file. ++ * gcc.target/arc/cmem-5.c: New file. ++ * gcc.target/arc/cmem-6.c: New file. ++ * gcc.target/arc/cmem-7.c: New file. ++ * gcc.target/arc/cmem-ld.inc: New file. ++ * gcc.target/arc/cmem-st.inc: New file. ++ + 2016-12-21 Release Manager + + * GCC 6.3.0 released. +diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c +new file mode 100644 +index 000000000000..7f36afbfa7d8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-1.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem"))); ++ ++#include "cmem-st.inc" ++ ++/* { dg-final { scan-assembler "xst " } } */ ++/* { dg-final { scan-assembler "xstw " } } */ ++/* { dg-final { scan-assembler "xstb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c +new file mode 100644 +index 000000000000..a3d7c130b5e8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-2.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem"))); ++ ++#include "cmem-ld.inc" ++ ++/* { dg-final { scan-assembler "xld " } } */ ++/* { dg-final { scan-assembler "xldw " } } */ ++/* { dg-final { scan-assembler "xldb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c +new file mode 100644 +index 000000000000..dee73b5c5d30 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-3.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private"))); ++ ++#include "cmem-st.inc" ++ ++/* { dg-final { scan-assembler "xst " } } */ ++/* { dg-final { scan-assembler "xstw " } } */ ++/* { dg-final { scan-assembler "xstb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c +new file mode 100644 +index 000000000000..1da6bce77c48 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-4.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private"))); ++ ++#include "cmem-ld.inc" ++ ++/* { dg-final { scan-assembler "xld " } } */ ++/* { dg-final { scan-assembler "xldw " } } */ ++/* { dg-final { scan-assembler "xldb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c +new file mode 100644 +index 000000000000..ad6904f73605 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-5.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared"))); ++ ++#include "cmem-st.inc" ++ ++/* { dg-final { scan-assembler "xst " } } */ ++/* { dg-final { scan-assembler "xstw " } } */ ++/* { dg-final { scan-assembler "xstb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c +new file mode 100644 +index 000000000000..24bc39bfd07c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-6.c +@@ -0,0 +1,10 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++#define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared"))); ++ ++#include "cmem-ld.inc" ++ ++/* { dg-final { scan-assembler "xld " } } */ ++/* { dg-final { scan-assembler "xldw " } } */ ++/* { dg-final { scan-assembler "xldb " } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c +new file mode 100644 +index 000000000000..72ee7bdffafb +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-7.c +@@ -0,0 +1,26 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mcmem" } */ ++ ++struct some_struct ++{ ++ unsigned char a; ++}; ++ ++unsigned char other_func (unsigned char); ++ ++unsigned char ++some_function () ++{ ++ static struct some_struct ss __attribute__ ((section (".cmem"))); ++ static struct some_struct tt; ++ ++ ss.a = other_func (ss.a); ++ tt.a = other_func (tt.a); ++ ++ return 0; ++} ++ ++/* { dg-final { scan-assembler "xldb \[^\n\]*@ss" } } */ ++/* { dg-final { scan-assembler "xstb \[^\n\]*@ss" } } */ ++/* { dg-final { scan-assembler-not "xldb \[^\n\]*@tt" } } */ ++/* { dg-final { scan-assembler-not "xstb \[^\n\]*@tt" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-ld.inc b/gcc/testsuite/gcc.target/arc/cmem-ld.inc +new file mode 100644 +index 000000000000..7b51bb39a174 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-ld.inc +@@ -0,0 +1,16 @@ ++ ++struct foo_type ++{ ++ unsigned int a; ++ unsigned short b; ++ unsigned char c; ++}; ++ ++struct foo_type foo __attribute__ ((section (".cmem"))); ++ ++unsigned int ++f () ++{ ++ unsigned int tmp = foo.a + foo.b + foo.c; ++ return tmp; ++} +diff --git a/gcc/testsuite/gcc.target/arc/cmem-st.inc b/gcc/testsuite/gcc.target/arc/cmem-st.inc +new file mode 100644 +index 000000000000..30aeace6609e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/cmem-st.inc +@@ -0,0 +1,18 @@ ++ ++struct foo_type ++{ ++ unsigned int a; ++ unsigned short b; ++ unsigned char c; ++}; ++ ++struct foo_type foo CMEM_SECTION_ATTR ++ ++int ++f () ++{ ++ foo.a = 3; ++ foo.b = 2; ++ foo.c = 1; ++ return 0; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0010-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0010-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch new file mode 100644 index 0000000..66be802 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0010-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch @@ -0,0 +1,1059 @@ +From e4b82df8479716978403370dfdde0a4a241306ab Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 18:48:43 +0000 +Subject: [PATCH 10/89] 2016-04-28 Joern Rennecke + Andrew Burgess + gcc: * config/arc/arc.h + (SYMBOL_FLAG_CMEM): Define. (TARGET_NPS_CMEM_DEFAULT): Provide + default definition. * config/arc/arc.c (arc_address_cost): Return 0 + for cmem_address. (arc_encode_section_info): Set SYMBOL_FLAG_CMEM + where indicated. * config/arc/arc.opt (mcmem): New option. * + config/arc/arc.md (*extendqihi2_i): Add r/Uex alternative, supply + length for r/m alternative. (*extendqisi2_ac): Likewise. + (*extendhisi2_i): Add r/Uex alternative, supply length for r/m and + r/Uex alternative. (movqi_insn): Add r/Ucm and Ucm/?Rac alternatives. + (movhi_insn): Likewise. (movsi_insn): Add r/Ucm,Ucm/w + alternatives. (*zero_extendqihi2_i): Add r/Ucm alternative. + (*zero_extendqisi2_ac): Likewise. (*zero_extendhisi2_i): Likewise. + * config/arc/constraints.md (Uex): New memory constraint. (Ucm): + New define_constraint. * config/arc/predicates.md + (long_immediate_loadstore_operand): Return 0 for MEM with + cmem_address address. (cmem_address_0): New predicates. + (cmem_address_1): Likewise. (cmem_address_2): Likewise. + (cmem_address): Likewise. gcc/testsuite: * gcc.target/arc/cmem-1.c: + New file. * gcc.target/arc/cmem-2.c: New file. * + gcc.target/arc/cmem-3.c: New file. * gcc.target/arc/cmem-4.c: New + file. * gcc.target/arc/cmem-5.c: New file. * + gcc.target/arc/cmem-6.c: New file. * gcc.target/arc/cmem-7.c: New + file. * gcc.target/arc/cmem-ld.inc: New file. * + gcc.target/arc/cmem-st.inc: New file. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235595 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 42 ++++ + gcc/config/arc/arc.c | 33 ++- + gcc/config/arc/arc.h | 9 + + gcc/config/arc/arc.md | 382 ++++++++++++++++++++++++++---- + gcc/config/arc/arc.opt | 4 + + gcc/config/arc/constraints.md | 58 ++++- + gcc/testsuite/ChangeLog | 16 ++ + gcc/testsuite/gcc.target/arc/extzv-1.c | 11 + + gcc/testsuite/gcc.target/arc/insv-1.c | 21 ++ + gcc/testsuite/gcc.target/arc/insv-2.c | 18 ++ + gcc/testsuite/gcc.target/arc/movb-1.c | 13 + + gcc/testsuite/gcc.target/arc/movb-2.c | 13 + + gcc/testsuite/gcc.target/arc/movb-3.c | 13 + + gcc/testsuite/gcc.target/arc/movb-4.c | 13 + + gcc/testsuite/gcc.target/arc/movb-5.c | 13 + + gcc/testsuite/gcc.target/arc/movb_cl-1.c | 9 + + gcc/testsuite/gcc.target/arc/movb_cl-2.c | 11 + + gcc/testsuite/gcc.target/arc/movbi_cl-1.c | 9 + + gcc/testsuite/gcc.target/arc/movl-1.c | 17 ++ + 19 files changed, 648 insertions(+), 57 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/extzv-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/insv-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/insv-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb-3.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb-4.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb-5.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/movb_cl-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/movbi_cl-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/movl-1.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index f0d877721dd3..5d03f67fa40b 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,6 +1,48 @@ + 2016-04-28 Joern Rennecke + Andrew Burgess + ++ * config/arc/arc.c (arc_conditional_register_usage): Take ++ TARGET_RRQ_CLASS into account. ++ (arc_print_operand): Support printing 'p' and 's' operands. ++ * config/arc/arc.h (TARGET_NPS_BITOPS_DEFAULT): Provide default ++ as 0. ++ (TARGET_RRQ_CLASS): Define. ++ (IS_POWEROF2_OR_0_P): Define. ++ * config/arc/arc.md (*movsi_insn): Add w/Clo, w/Chi, and w/Cbi ++ alternatives. ++ (*tst_movb): New define_insn. ++ (*tst): Avoid recognition if it could prevent '*tst_movb' ++ combination; replace c/CnL with c/Chs alternative. ++ (*tst_bitfield_tst): New define_insn. ++ (*tst_bitfield_asr): New define_insn. ++ (*tst_bitfield): New define_insn. ++ (andsi3_i): Add Rrq variant. ++ (extzv): New define_expand. ++ (insv): New define_expand. ++ (*insv_i): New define_insn. ++ (*movb): New define_insn. ++ (*movb_signed): New define_insn. ++ (*movb_high): New define_insn. ++ (*movb_high_signed): New define_insn. ++ (*movb_high_signed + 1): New define_split pattern. ++ (*mrgb): New define_insn. ++ (*mrgb + 1): New define_peephole2 pattern. ++ (*mrgb + 2): New define_peephole2 pattern. ++ * config/arc/arc.opt (mbitops): New option for nps400, uses ++ TARGET_NPS_BITOPS_DEFAULT. ++ * config/arc/constraints.md (q): Make register class conditional. ++ (Rrq): New register constraint. ++ (Chs): New constraint. ++ (Clo): New constraint. ++ (Chi): New constraint. ++ (Cbf): New constraint. ++ (Cbn): New constraint. ++ (C18): New constraint. ++ (Cbi): New constraint. ++ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ + * config/arc/constraints.md (Usd): Convert to define_constraint. + (Us<): Likewise. + (Us>): Likewise. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index ca9d31ceee95..b7dfab1e0d86 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1430,7 +1430,8 @@ arc_conditional_register_usage (void) + { + if (i < 29) + { +- if (TARGET_Q_CLASS && ((i <= 3) || ((i >= 12) && (i <= 15)))) ++ if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS) ++ && ((i <= 3) || ((i >= 12) && (i <= 15)))) + arc_regno_reg_class[i] = ARCOMPACT16_REGS; + else + arc_regno_reg_class[i] = GENERAL_REGS; +@@ -1447,12 +1448,12 @@ arc_conditional_register_usage (void) + arc_regno_reg_class[i] = NO_REGS; + } + +- /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS has not been activated. */ ++ /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS ++ has not been activated. */ ++ if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS) ++ CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]); + if (!TARGET_Q_CLASS) +- { +- CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]); +- CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]); +- } ++ CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]); + + gcc_assert (FIRST_PSEUDO_REGISTER >= 144); + +@@ -2994,6 +2995,8 @@ static int output_scaled = 0; + 'Z': log2(x+1)-1 + 'z': log2 + 'M': log2(~x) ++ 'p': bit Position of lsb ++ 's': size of bit field + '#': condbranch delay slot suffix + '*': jump delay slot suffix + '?' : nonjump-insn suffix for conditional execution or short instruction +@@ -3044,6 +3047,24 @@ arc_print_operand (FILE *file, rtx x, int code) + + return; + ++ case 'p': ++ if (GET_CODE (x) == CONST_INT) ++ fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x))); ++ else ++ output_operand_lossage ("invalid operand to %%p code"); ++ return; ++ ++ case 's': ++ if (GET_CODE (x) == CONST_INT) ++ { ++ HOST_WIDE_INT i = INTVAL (x); ++ HOST_WIDE_INT s = exact_log2 (i & -i); ++ fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1)); ++ } ++ else ++ output_operand_lossage ("invalid operand to %%s code"); ++ return; ++ + case '#' : + /* Conditional branches depending on condition codes. + Note that this is only for branches that were known to depend on +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index a17d41092507..4235eabc96d3 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -326,10 +326,18 @@ along with GCC; see the file COPYING3. If not see + #define UNALIGNED_ACCESS_DEFAULT 0 + #endif + ++#ifndef TARGET_NPS_BITOPS_DEFAULT ++#define TARGET_NPS_BITOPS_DEFAULT 0 ++#endif ++ + #ifndef TARGET_NPS_CMEM_DEFAULT + #define TARGET_NPS_CMEM_DEFAULT 0 + #endif + ++/* Enable the RRQ instruction alternatives. */ ++ ++#define TARGET_RRQ_CLASS TARGET_NPS_BITOPS ++ + /* Target machine storage layout. */ + + /* We want zero_extract to mean the same +@@ -1033,6 +1041,7 @@ extern int arc_initial_elimination_offset(int from, int to); + + /* Is the argument a const_int rtx, containing an exact power of 2 */ + #define IS_POWEROF2_P(X) (! ( (X) & ((X) - 1)) && (X)) ++#define IS_POWEROF2_OR_0_P(X) (! ( (X) & ((X) - 1))) + + /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx + and check its validity for a certain class. +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 93a2cad7dfa6..7c30eb46e072 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -700,8 +700,8 @@ + ; insns it should lengthen the return insn. + ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . + (define_insn "*movsi_insn" +- [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w, w,w, w,???w, ?w, w,Rcq#q, w,Rcq, S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") +- (match_operand:SI 1 "move_src_operand" " cL,cP,Rcq#q,cL,I,Crr,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] ++ [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") ++ (match_operand:SI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || (CONSTANT_P (operands[1]) +@@ -716,29 +716,32 @@ + mov%? %0,%1 ;3 + mov%? %0,%1 ;4 + ror %0,((%1*2+1) & 0x3f) ;5 +- mov%? %0,%1 ;6 +- add %0,%S1 ;7 ++ movl.cl %0,%1 ;6 ++ movh.cl %0,%L1>>16 ;7 ++ * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\"; ++ mov%? %0,%1 ;9 ++ add %0,%S1 ;10 + * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; +- mov%? %0,%S1%& ;9 +- mov%? %0,%S1 ;10 +- ld%? %0,%1%& ;11 +- st%? %1,%0%& ;12 ++ mov%? %0,%S1%& ;12 ++ mov%? %0,%S1 ;13 ++ ld%? %0,%1%& ;14 ++ st%? %1,%0%& ;15 + * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); + * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); +- ld%? %0,%1%& ;15 +- xld%U1 %0,%1 ;16 +- ld%U1%V1 %0,%1 ;17 +- xst%U0 %1,%0 ;18 +- st%U0%V0 %1,%0 ;19 +- st%U0%V0 %1,%0 ;20 +- st%U0%V0 %S1,%0 ;21" +- [(set_attr "type" "move,move,move,move,move,two_cycle_core,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") ++ ld%? %0,%1%& ;18 ++ xld%U1 %0,%1 ;19 ++ ld%U1%V1 %0,%1 ;20 ++ xst%U0 %1,%0 ;21 ++ st%U0%V0 %1,%0 ;22 ++ st%U0%V0 %1,%0 ;23 ++ st%U0%V0 %S1,%0 ;24" ++ [(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") + ; Use default length for iscompact to allow for COND_EXEC. But set length + ; of Crr to 4. +- (set_attr "length" "*,*,*,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") +- (set_attr "predicable" "yes,no,yes,yes,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") ++ (set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + + ;; Sometimes generated by the epilogue code. We don't want to + ;; recognize these addresses in general, because the limm is costly, +@@ -809,6 +812,24 @@ + (set_attr "cond" "set_zn") + (set_attr "length" "4")]) + ++; reload is too stingy with reloads for Rrq/Cbf/Rrq when it sees ++; a c/???Cal/X alternative, so we say it's c/???Cal/c instead, ++; even if we don't need the clobber. ++(define_insn_and_split "*tst_movb" ++ [(set ++ (match_operand 0 "cc_register" "") ++ (match_operator 4 "zn_compare_operator" ++ [(and:SI ++ (match_operand:SI 1 "register_operand" "%Rcq,Rcq, c, c, c, c,Rrq, 3, c") ++ (match_operand:SI 2 "nonmemory_operand" "Rcq,C0p,cI,C1p,Ccp,Chs,Cbf,Cbf,???Cal")) ++ (const_int 0)])) ++ (clobber (match_scratch:SI 3 "=X,X,X,X,X,X,Rrq,Rrq,c"))] ++ "TARGET_NPS_BITOPS" ++ "movb.f.cl %3,%1,%p2,%p2,%s2" ++ "reload_completed ++ && (extract_constrain_insn_cached (insn), (which_alternative & ~1) != 6)" ++ [(set (match_dup 0) (match_dup 4))]) ++ + (define_insn "*tst" + [(set + (match_operand 0 "cc_register" "") +@@ -817,12 +838,14 @@ + (match_operand:SI 1 "register_operand" + "%Rcq,Rcq, c, c, c, c, c, c") + (match_operand:SI 2 "nonmemory_operand" +- " Rcq,C0p,cI,cL,C1p,Ccp,CnL,Cal")) ++ " Rcq,C0p,cI,cL,C1p,Ccp,Chs,Cal")) + (const_int 0)]))] +- "(register_operand (operands[1], SImode) +- && nonmemory_operand (operands[2], SImode)) +- || (memory_operand (operands[1], SImode) +- && satisfies_constraint_Cux (operands[2]))" ++ "reload_completed ++ || !satisfies_constraint_Cbf (operands[2]) ++ || satisfies_constraint_C0p (operands[2]) ++ || satisfies_constraint_I (operands[2]) ++ || satisfies_constraint_C1p (operands[2]) ++ || satisfies_constraint_Chs (operands[2])" + "* + switch (which_alternative) + { +@@ -835,17 +858,79 @@ + case 5: + return \"bclr%?.f 0,%1,%M2%&\"; + case 6: +- return \"bic%?.f 0,%1,%n2-1\"; ++ return \"asr.f 0,%1,%p2\"; + default: + gcc_unreachable (); + } + " + [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false") +- (set_attr "type" "compare") ++ (set_attr "type" "compare,compare,compare,compare,compare,compare,shift,compare") + (set_attr "length" "*,*,4,4,4,4,4,8") + (set_attr "predicable" "no,yes,no,yes,no,no,no,yes") + (set_attr "cond" "set_zn")]) + ++; ??? Sometimes, if an AND with a constant can be expressed as a zero_extract, ++; combine will do that and not try the AND. ++ ++; It would take 66 constraint combinations to describe the zero_extract ++; constants that are covered by the 12-bit signed constant for tst ++; (excluding the ones that are better done by mov or btst). ++; so we rather use an extra pattern for tst; ++; since this is about constants, reload shouldn't care. ++(define_insn "*tst_bitfield_tst" ++ [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ (match_operator 4 "zn_compare_operator" ++ [(zero_extract:SI ++ (match_operand:SI 1 "register_operand" "c") ++ (match_operand:SI 2 "const_int_operand" "n") ++ (match_operand:SI 3 "const_int_operand" "n")) ++ (const_int 0)]))] ++ "INTVAL (operands[2]) > 1 ++ && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11 ++ || (INTVAL (operands[3]) <= 11 ++ && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))" ++ "tst %1,(1<<%2)-1<<%3" ++ [(set_attr "type" "compare") ++ (set_attr "cond" "set_zn") ++ (set_attr "length" "4")]) ++ ++; Likewise for asr.f. ++(define_insn "*tst_bitfield_asr" ++ [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ (match_operator 4 "zn_compare_operator" ++ [(zero_extract:SI ++ (match_operand:SI 1 "register_operand" "c") ++ (match_operand:SI 2 "const_int_operand" "n") ++ (match_operand:SI 3 "const_int_operand" "n")) ++ (const_int 0)]))] ++ "INTVAL (operands[2]) > 1 ++ && INTVAL (operands[3]) + INTVAL (operands[2]) == 32" ++ "asr.f 0,%1,%3" ++ [(set_attr "type" "shift") ++ (set_attr "cond" "set_zn") ++ (set_attr "length" "4")]) ++ ++(define_insn "*tst_bitfield" ++ [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ (match_operator 5 "zn_compare_operator" ++ [(zero_extract:SI ++ (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c") ++ (match_operand:SI 2 "const_int_operand" "N,N, n,Cbn,n") ++ (match_operand:SI 3 "const_int_operand" "n,n,C_0,Cbn,n")) ++ (const_int 0)])) ++ (clobber (match_scratch:SI 4 "=X,X,X,Rrq,X"))] ++ "" ++ "@ ++ btst%? %1,%3 ++ btst %1,%3 ++ bmsk.f 0,%1,%2-1 ++ movb.f.cl %4,%1,%3,%3,%2 ++ and.f 0,%1,((1<<%2)-1)<<%3" ++ [(set_attr "iscompact" "maybe,false,false,false,false") ++ (set_attr "type" "compare,compare,compare,shift,compare") ++ (set_attr "cond" "set_zn") ++ (set_attr "length" "*,4,4,4,8")]) ++ + (define_insn "*commutative_binary_comparison" + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator:CC_ZN 5 "zn_compare_operator" +@@ -2956,30 +3041,40 @@ + operands[1] = arc_rewrite_small_data (operands[1]);") + + (define_insn "andsi3_i" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw, w, w, w, w,w,Rcw, w, W") +- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,0, 0, c, o") +- (match_operand:SI 2 "nonmemory_operand" " Rcqq, 0, C1p, Ccp, Cux, cL, 0,C1p,Ccp,CnL, I, Lc,C1p,Ccp,CnL,I,Cal,Cal,Cux")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W") ++ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o") ++ (match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] + "(register_operand (operands[1], SImode) + && nonmemory_operand (operands[2], SImode)) + || (memory_operand (operands[1], SImode) + && satisfies_constraint_Cux (operands[2]))" +- "* + { + switch (which_alternative) + { +- case 0: case 5: case 10: case 11: case 15: case 16: case 17: +- return \"and%? %0,%1,%2%&\"; ++ case 0: case 5: case 10: case 11: case 16: case 17: case 18: ++ return "and%? %0,%1,%2%&"; + case 1: case 6: +- return \"and%? %0,%2,%1%&\"; ++ return "and%? %0,%2,%1%&"; + case 2: case 7: case 12: +- return \"bmsk%? %0,%1,%Z2%&\"; ++ return "bmsk%? %0,%1,%Z2%&"; + case 3: case 8: case 13: +- return \"bclr%? %0,%1,%M2%&\"; ++ return "bclr%? %0,%1,%M2%&"; + case 4: + return (INTVAL (operands[2]) == 0xff +- ? \"extb%? %0,%1%&\" : \"ext%_%? %0,%1%&\"); ++ ? "extb%? %0,%1%&" : "ext%_%? %0,%1%&"); + case 9: case 14: return \"bic%? %0,%1,%n2-1\"; +- case 18: ++ case 15: ++ return "movb.cl %0,%1,%p2,%p2,%s2"; ++ ++ case 19: ++ const char *tmpl; ++ ++ if (satisfies_constraint_Ucm (operands[1])) ++ tmpl = (INTVAL (operands[2]) == 0xff ++ ? "xldb%U1 %0,%1" : "xld%_%U1 %0,%1"); ++ else ++ tmpl = INTVAL (operands[2]) == 0xff ? "ldb %0,%1" : "ld%_ %0,%1"; ++ + if (TARGET_BIG_ENDIAN) + { + rtx xop[2]; +@@ -2987,21 +3082,19 @@ + xop[0] = operands[0]; + xop[1] = adjust_address (operands[1], QImode, + INTVAL (operands[2]) == 0xff ? 3 : 2); +- output_asm_insn (INTVAL (operands[2]) == 0xff +- ? \"ldb %0,%1\" : \"ld%_ %0,%1\", +- xop); +- return \"\"; ++ output_asm_insn (tmpl, xop); ++ return ""; + } +- return INTVAL (operands[2]) == 0xff ? \"ldb %0,%1\" : \"ld%_ %0,%1\"; ++ return tmpl; + default: + gcc_unreachable (); + } +-}" +- [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false") +- (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,load") +- (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,8,8,*") +- (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,yes,no,no") +- (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) ++} ++ [(set_attr "iscompact" "maybe,maybe,maybe,maybe,true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false") ++ (set_attr "type" "binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,binary,shift,binary,binary,binary,load") ++ (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,4,4,4,4,4,8,8,*") ++ (set_attr "predicable" "no,no,no,no,no,yes,yes,yes,yes,yes,no,no,no,no,no,no,no,yes,no,no") ++ (set_attr "cond" "canuse,canuse,canuse,canuse,nocond,canuse,canuse,canuse,canuse,canuse,canuse_limm,nocond,nocond,nocond,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) + + ; combiner splitter, pattern found in ldtoa.c . + ; and op3,op0,op1 / cmp op3,op2 -> add op3,op0,op4 / bmsk.f 0,op3,op1 +@@ -5717,7 +5810,6 @@ + [(set_attr "length" "4") + (set_attr "type" "misc")]) + +- + ;; FPU/FPX expands + + ;;add +@@ -5862,6 +5954,196 @@ + gcc_unreachable (); + ") + ++(define_expand "extzv" ++ [(set (match_operand:SI 0 "register_operand" "") ++ (zero_extract:SI (match_operand:SI 1 "register_operand" "") ++ (match_operand:SI 2 "const_int_operand" "") ++ (match_operand:SI 3 "const_int_operand" "")))] ++ "TARGET_NPS_BITOPS") ++ ++; We need a sanity check in the instuction predicate because combine ++; will throw any old rubbish at us and see what sticks. ++(define_insn "*extzv_i" ++ [(set (match_operand:SI 0 "register_operand" "=Rrq") ++ (zero_extract:SI (match_operand:SI 1 "register_operand" "Rrq") ++ (match_operand:SI 2 "const_int_operand" "n") ++ (match_operand:SI 3 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32" ++ "movb.cl %0,%1,0,%3,%2" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++(define_expand "insv" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "") ++ (match_operand:SI 1 "const_int_operand" "") ++ (match_operand:SI 2 "const_int_operand" "")) ++ (match_operand:SI 3 "nonmemory_operand" ""))] ++ "TARGET_NPS_BITOPS" ++{ ++ int size = INTVAL (operands[1]); ++ ++ if (size != 1 && size != 2 && size != 4 && size != 8) ++ operands[3] = force_reg (SImode, operands[3]); ++}) ++ ++(define_insn "*insv_i" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+w,Rrq") ++ (match_operand:SI 1 "const_int_operand" "C18,n") ++ (match_operand:SI 2 "const_int_operand" "n,n")) ++ (match_operand:SI 3 "nonmemory_operand" "P,Rrq"))] ++ "TARGET_NPS_BITOPS ++ && (register_operand (operands[3], SImode) ++ || satisfies_constraint_C18 (operands[1]))" ++ "@ ++ movbi %0,%0,%3,%2,%1 ++ movb %0,%0,%3,%2,0,%1" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++(define_insn "*movb" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") ++ (match_operand:SI 1 "const_int_operand" "n") ++ (match_operand:SI 2 "const_int_operand" "n")) ++ (zero_extract:SI (match_operand:SI 3 "register_operand" "Rrq") ++ (match_dup 1) ++ (match_operand:SI 4 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS" ++ "movb %0,%0,%3,%2,%4,%1" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++(define_insn "*movb_signed" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") ++ (match_operand:SI 1 "const_int_operand" "n") ++ (match_operand:SI 2 "const_int_operand" "n")) ++ (sign_extract:SI (match_operand:SI 3 "register_operand" "Rrq") ++ (match_dup 1) ++ (match_operand:SI 4 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS" ++ "movb %0,%0,%3,%2,%4,%1" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++(define_insn "*movb_high" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") ++ (match_operand:SI 1 "const_int_operand" "n") ++ (match_operand:SI 2 "const_int_operand" "n")) ++ (lshiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") ++ (match_operand:SI 4 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS ++ && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" ++ "movb %0,%0,%3,%2,%4,%1" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++; N.B.: when processing signed bitfields that fit in the top half of ++; a word, gcc will use a narrow sign extending load, and in this case ++; we will see INTVAL (operands[4]) + INTVAL (operands[1]) == 16 (or 8) ++(define_insn "*movb_high_signed" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") ++ (match_operand:SI 1 "const_int_operand" "n") ++ (match_operand:SI 2 "const_int_operand" "n")) ++ (ashiftrt:SI (match_operand:SI 3 "register_operand" "Rrq") ++ (match_operand:SI 4 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS ++ && INTVAL (operands[4]) + INTVAL (operands[1]) <= 32" ++ "movb %0,%0,%3,%2,%4,%1" ++ [(set_attr "type" "shift") ++ (set_attr "length" "4")]) ++ ++(define_split ++ [(set (match_operand:SI 0 "register_operand" "") ++ (ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "") ++ (match_operand:SI 2 "const_int_operand" "")) ++ (subreg:SI (match_operand 3 "") 0)))] ++ "TARGET_NPS_BITOPS ++ && GET_MODE_BITSIZE (GET_MODE (operands[3])) <= INTVAL (operands[2]) ++ && !reg_overlap_mentioned_p (operands[0], operands[1])" ++ [(set (match_dup 0) (zero_extend:SI (match_dup 3))) ++ (set (zero_extract:SI (match_dup 0) (match_dup 4) (match_dup 2)) ++ (match_dup 1))] ++ "operands[4] = GEN_INT (32 - INTVAL (operands[2]));") ++ ++(define_insn "*mrgb" ++ [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+Rrq") ++ (match_operand:SI 1 "const_int_operand" "n") ++ (match_operand:SI 2 "const_int_operand" "n")) ++ (zero_extract:SI (match_dup 0) (match_dup 1) ++ (match_operand:SI 3 "const_int_operand" "n"))) ++ (set (zero_extract:SI (match_dup 0) ++ (match_operand:SI 4 "const_int_operand" "n") ++ (match_operand:SI 5 "const_int_operand" "n")) ++ (zero_extract:SI (match_operand:SI 6 "register_operand" "Rrq") ++ (match_dup 4) ++ (match_operand:SI 7 "const_int_operand" "n")))] ++ "TARGET_NPS_BITOPS" ++{ ++ output_asm_insn ("mrgb %0,%0,%6,%2,%3,%1,%5,%7,%4", operands); ++ /* The ;%? updates the known unalignment. */ ++ return arc_short_long (insn, ";%?", "nop_s"); ++} ++ [(set_attr "type" "shift") ++ (set_attr "length" "6") ++ (set_attr "iscompact" "true")]) ++ ++;; combine fumbles combination of two movb patterns, and then the ++;; combination is rejected by combinable_i3pat. ++;; Thus, we can only use a peephole2 to combine two such insns. ++ ++(define_peephole2 ++ [(set (match_operand:SI 0 "register_operand" "") ++ (match_operand:SI 1 "register_operand" "")) ++ (set (zero_extract:SI (match_dup 0) ++ (match_operand:SI 2 "const_int_operand" "") ++ (match_operand:SI 3 "const_int_operand" "")) ++ (zero_extract:SI (match_dup 1) ++ (match_dup 2) ++ (match_operand:SI 4 "const_int_operand" ""))) ++ (match_operand 9) ; unrelated insn scheduled here ++ (set (zero_extract:SI (match_dup 0) ++ (match_operand:SI 5 "const_int_operand" "") ++ (match_operand:SI 6 "const_int_operand" "")) ++ (zero_extract:SI (match_operand:SI 7 "register_operand" "") ++ (match_dup 5) ++ (match_operand:SI 8 "const_int_operand" "")))] ++ "TARGET_NPS_BITOPS ++ // Check that the second movb doesn't clobber an input of the extra insn. ++ && !reg_overlap_mentioned_p (operands[0], operands[9]) ++ // And vice versa. ++ && !reg_set_p (operands[0], operands[9]) ++ && !reg_set_p (operands[7], operands[9])" ++ [(set (match_dup 0) (match_dup 1)) ++ (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) ++ (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4))) ++ (set (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)) ++ (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 4)))]) ++ (match_dup 9)]) ++ ++(define_peephole2 ++ [(set (match_operand:SI 0 "register_operand" "") ++ (match_operand:SI 1 "register_operand" "")) ++ (set (zero_extract:SI (match_dup 0) ++ (match_operand:SI 2 "const_int_operand" "") ++ (match_operand:SI 3 "const_int_operand" "")) ++ (zero_extract:SI (match_dup 1) ++ (match_dup 2) ++ (match_operand:SI 4 "const_int_operand" ""))) ++ (set (match_dup 1) (match_operand 8)) ++ (set (zero_extract:SI (match_dup 0) ++ (match_operand:SI 5 "const_int_operand" "") ++ (match_operand:SI 6 "const_int_operand" "")) ++ (zero_extract:SI (match_dup 1) (match_dup 5) ++ (match_operand:SI 7 "const_int_operand" "")))] ++ "TARGET_NPS_BITOPS ++ && !reg_overlap_mentioned_p (operands[0], operands[8])" ++ [(set (match_dup 0) (match_dup 1)) ++ (set (match_dup 1) (match_dup 8)) ++ (parallel [(set (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 3)) ++ (zero_extract:SI (match_dup 0) (match_dup 2) (match_dup 4))) ++ (set (zero_extract:SI (match_dup 0) (match_dup 5) (match_dup 6)) ++ (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) ++ (match_dup 1)]) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index b2c7b3763c1d..d957a92dd6f0 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -470,6 +470,10 @@ Specify thread pointer register number + mtp-regno=none + Target RejectNegative Var(arc_tp_regno,-1) + ++mbitops ++Target Report Var(TARGET_NPS_BITOPS) Init(TARGET_NPS_BITOPS_DEFAULT) ++Enable use of NPS400 bit operations. ++ + mcmem + Target Report Var(TARGET_NPS_CMEM) Init(TARGET_NPS_CMEM_DEFAULT) + Enable use of NPS400 xld/xst extension. +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index c2992c9e9473..f30572c48579 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -66,10 +66,18 @@ + Link Registers @code{ilink1}:@code{r29}, @code{ilink2}:@code{r30}, + @code{blink}:@code{r31},") + +-(define_register_constraint "q" "ARCOMPACT16_REGS" ++(define_register_constraint "q" "TARGET_Q_CLASS ? ARCOMPACT16_REGS : NO_REGS" + "Registers usable in ARCompact 16-bit instructions: @code{r0}-@code{r3}, + @code{r12}-@code{r15}") + ++; NPS400 bitfield instructions require registers from the r0-r3,r12-r15 ++; range, and thus we need a register class and constraint that works ++; independently of size optimization. ++(define_register_constraint ++ "Rrq" "TARGET_RRQ_CLASS ? ARCOMPACT16_REGS : NO_REGS" ++ "Registers usable in NPS400 bitfield instructions: @code{r0}-@code{r3}, ++ @code{r12}-@code{r15}") ++ + (define_register_constraint "e" "AC16_BASE_REGS" + "Registers usable as base-regs of memory addresses in ARCompact 16-bit memory + instructions: @code{r0}-@code{r3}, @code{r12}-@code{r15}, @code{sp}") +@@ -236,12 +244,60 @@ + (and (match_code "const_int") + (match_test "ival == 0xff || ival == 0xffff"))) + ++(define_constraint "Chs" ++ "@internal ++ constant for a highpart that can be checked with a shift (asr.f 0,rn,m)" ++ (and (match_code "const_int") ++ (match_test "IS_POWEROF2_P (-ival)"))) ++ ++(define_constraint "Clo" ++ "@internal ++ constant that fits into 16 lower bits, for movl" ++ (and (match_code "const_int") ++ (match_test "TARGET_NPS_BITOPS") ++ (match_test "(ival & ~0xffffU) == 0"))) ++ ++(define_constraint "Chi" ++ "@internal ++ constant that fits into 16 higher bits, for movh_i" ++ (and (match_code "const_int") ++ (match_test "TARGET_NPS_BITOPS") ++ (match_test "trunc_int_for_mode (ival >> 16, HImode) << 16 == ival"))) ++ ++(define_constraint "Cbf" ++ "@internal ++ a mask for a bit field, for AND using movb_i" ++ (and (match_code "const_int") ++ (match_test "TARGET_NPS_BITOPS") ++ (match_test "IS_POWEROF2_OR_0_P (ival + (ival & -ival))"))) ++ ++(define_constraint "Cbn" ++ "@internal ++ a constant integer, valid only if TARGET_NPS_BITOPS is true" ++ (and (match_code "const_int") ++ (match_test "TARGET_NPS_BITOPS"))) ++ ++(define_constraint "C18" ++ "@internal ++ 1,2,4 or 8" ++ (and (match_code "const_int") ++ (match_test "ival == 1 || ival == 2 || ival == 4 || ival == 8"))) ++ + (define_constraint "Crr" + "@internal + constant that can be loaded with ror b,u6" + (and (match_code "const_int") + (match_test "(ival & ~0x8000001f) == 0 && !arc_ccfsm_cond_exec_p ()"))) + ++(define_constraint "Cbi" ++ "@internal ++ constant that can be loaded with movbi.cl" ++ (and (match_code "const_int") ++ (match_test "TARGET_NPS_BITOPS") ++ (match_test "!ival ++ || ((ival & 0xffffffffUL) >> exact_log2 (ival & -ival) ++ <= 0xff)"))) ++ + ;; Floating-point constraints + + (define_constraint "G" +diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog +index 63a13b84ee10..369383fbd07c 100644 +--- a/gcc/testsuite/ChangeLog ++++ b/gcc/testsuite/ChangeLog +@@ -1,6 +1,22 @@ + 2016-04-28 Joern Rennecke + Andrew Burgess + ++ * gcc.target/arc/extzv-1.c: New file. ++ * gcc.target/arc/insv-1.c: New file. ++ * gcc.target/arc/insv-2.c: New file. ++ * gcc.target/arc/movb-1.c: New file. ++ * gcc.target/arc/movb-2.c: New file. ++ * gcc.target/arc/movb-3.c: New file. ++ * gcc.target/arc/movb-4.c: New file. ++ * gcc.target/arc/movb-5.c: New file. ++ * gcc.target/arc/movb_cl-1.c: New file. ++ * gcc.target/arc/movb_cl-2.c: New file. ++ * gcc.target/arc/movbi_cl-1.c: New file. ++ * gcc.target/arc/movl-1.c: New file. ++ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ + * gcc.target/arc/cmem-1.c: New file. + * gcc.target/arc/cmem-2.c: New file. + * gcc.target/arc/cmem-3.c: New file. +diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c +new file mode 100644 +index 000000000000..242f522f187e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/extzv-1.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct foo { unsigned a: 3, b: 5, c: 24; }; ++ ++int ++f (struct foo i) ++{ ++ return i.b; ++} ++/* { dg-final { scan-assembler "movb\.cl" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c +new file mode 100644 +index 000000000000..75d47e9b1b3f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/insv-1.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++/* ??? Irrespective of insn set, generated code for this is a mess. */ ++struct foo { unsigned a: 3, b: 8, c: 21; }; ++ ++struct foo ++f (struct foo i) ++{ ++ i.b = 42; ++ return i; ++} ++ ++struct foo ++g (struct foo i, int j) ++{ ++ i.b = j; ++ return i; ++} ++/* { dg-final { scan-assembler "movbi\[ \t\]" } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c +new file mode 100644 +index 000000000000..16525511698c +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/insv-2.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct foo { unsigned a: 3, b: 8, c: 21; } bar; ++ ++void ++f (void) ++{ ++ bar.b = 42; ++} ++ ++void ++g (int j) ++{ ++ bar.b = j; ++} ++/* { dg-final { scan-assembler "movbi\[ \t\]" } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c +new file mode 100644 +index 000000000000..65d4ba4b6ab4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb-1.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct { unsigned a: 5, b: 8, c: 19; } foo; ++struct { unsigned a: 3, b: 8, c: 21; } bar; ++ ++void ++f (void) ++{ ++ bar.b = foo.b; ++} ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c +new file mode 100644 +index 000000000000..1ba9976a566d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb-2.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct { unsigned a: 23, b: 9; } foo; ++struct { unsigned a: 23, b: 9; } bar; ++ ++void ++f (void) ++{ ++ bar.b = foo.b; ++} ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c +new file mode 100644 +index 000000000000..0895154abb67 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb-3.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct { int a: 23, b: 9; } foo; ++struct { int a: 23, b: 9; } bar; ++ ++void ++f (void) ++{ ++ bar.a = foo.a; ++} ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *23" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *9, *9, *23" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c +new file mode 100644 +index 000000000000..89bf2c2b1232 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb-4.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct { int a: 13, b: 19; } foo; ++struct { int a: 13, b: 19; } bar; ++ ++void ++f (void) ++{ ++ bar.b = foo.b; ++} ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *13, *13, *19" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *19" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c +new file mode 100644 +index 000000000000..9dbe8a1e09a8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb-5.c +@@ -0,0 +1,13 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct { int a: 23, b: 9; } foo; ++struct { int a: 23, b: 9; } bar; ++ ++void ++f (void) ++{ ++ bar.b = foo.b; ++} ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c +new file mode 100644 +index 000000000000..402250ce5302 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++int ++f (int i) ++{ ++ return i & 0x0ffff000; ++} ++/* { dg-final { scan-assembler "movb\.cl" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c +new file mode 100644 +index 000000000000..d2e5a944a6ea +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c +@@ -0,0 +1,11 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++extern void g (void); ++int ++f (int i) ++{ ++ if (i & 0x0ffff000) ++ g (); ++} ++/* { dg-final { scan-assembler "movb\.f\.cl" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c +new file mode 100644 +index 000000000000..3c457dbe5287 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c +@@ -0,0 +1,9 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++int ++f (int i) ++{ ++ return 0x6e00; ++} ++/* { dg-final { scan-assembler "mov(bi|l)\.cl" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c +new file mode 100644 +index 000000000000..f1f0130a2b07 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movl-1.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++int ++f (void) ++{ ++ return 0xd00d; ++} ++ ++int ++g (void) ++{ ++ return 0x7ff00000; ++} ++ ++/* { dg-final { scan-assembler "movl\.cl\[ \t\]" } } */ ++/* { dg-final { scan-assembler "movh\.cl\[ \t\]" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0011-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0011-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch new file mode 100644 index 0000000..b29b994 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0011-2016-04-28-Joern-Rennecke-joern.rennecke-embecosm.co.patch @@ -0,0 +1,116 @@ +From b1ed7be8931f71e970c8cffc65615421e9cd0d3e Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 19:08:28 +0000 +Subject: [PATCH 11/89] 2016-04-28 Joern Rennecke + Andrew Burgess + gcc: * config/arc/arc.c + (arc_print_operand): Print integer 'H' / 'L' gcc/testsuite: * + gcc.target/arc/movh_cl-1.c: New file. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235600 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 6 ++++++ + gcc/config/arc/arc.c | 12 +++++------- + gcc/testsuite/ChangeLog | 5 +++++ + gcc/testsuite/gcc.target/arc/movh_cl-1.c | 27 +++++++++++++++++++++++++++ + 4 files changed, 43 insertions(+), 7 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/movh_cl-1.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 5d03f67fa40b..0d4a3c076c27 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,6 +1,12 @@ + 2016-04-28 Joern Rennecke + Andrew Burgess + ++ * config/arc/arc.c (arc_print_operand): Print integer 'H' / 'L' ++ operands as 32-bits. ++ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ + * config/arc/arc.c (arc_conditional_register_usage): Take + TARGET_RRQ_CLASS into account. + (arc_print_operand): Support printing 'p' and 's' operands. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index b7dfab1e0d86..dfaea7b92412 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -3235,19 +3235,17 @@ arc_print_operand (FILE *file, rtx x, int code) + else if (GET_CODE (x) == CONST_INT + || GET_CODE (x) == CONST_DOUBLE) + { +- rtx first, second; ++ rtx first, second, word; + + split_double (x, &first, &second); + + if((WORDS_BIG_ENDIAN) == 0) +- fprintf (file, "0x%08" PRIx64, +- code == 'L' ? INTVAL (first) : INTVAL (second)); ++ word = (code == 'L' ? first : second); + else +- fprintf (file, "0x%08" PRIx64, +- code == 'L' ? INTVAL (second) : INTVAL (first)); ++ word = (code == 'L' ? second : first); + +- +- } ++ fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word))); ++ } + else + output_operand_lossage ("invalid operand to %%H/%%L code"); + return; +diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog +index 369383fbd07c..0f7f4b561168 100644 +--- a/gcc/testsuite/ChangeLog ++++ b/gcc/testsuite/ChangeLog +@@ -1,6 +1,11 @@ + 2016-04-28 Joern Rennecke + Andrew Burgess + ++ * gcc.target/arc/movh_cl-1.c: New file. ++ ++2016-04-28 Joern Rennecke ++ Andrew Burgess ++ + * gcc.target/arc/extzv-1.c: New file. + * gcc.target/arc/insv-1.c: New file. + * gcc.target/arc/insv-2.c: New file. +diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +new file mode 100644 +index 000000000000..220cd9d72b94 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +@@ -0,0 +1,27 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ ++ ++struct thing ++{ ++ union ++ { ++ int raw; ++ struct ++ { ++ unsigned a : 1; ++ unsigned b : 1; ++ }; ++ }; ++}; ++ ++extern void func (int); ++ ++void ++blah () ++{ ++ struct thing xx; ++ xx.a = xx.b = 1; ++ func (xx.raw); ++} ++ ++/* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0012-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0012-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch new file mode 100644 index 0000000..38f79f5 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0012-2016-04-28-Andrew-Burgess-andrew.burgess-embecosm.co.patch @@ -0,0 +1,59 @@ +From 27f2e619d6523420c05e58d63121eebf3e2bf9af Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Thu, 28 Apr 2016 19:13:47 +0000 +Subject: [PATCH 12/89] 2016-04-28 Andrew Burgess + + + * gcc.target/arc/nps400-1.c: New file. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235603 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/testsuite/ChangeLog | 4 ++++ + gcc/testsuite/gcc.target/arc/nps400-1.c | 23 +++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/arc/nps400-1.c + +diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog +index 0f7f4b561168..7d583c8d99dc 100644 +--- a/gcc/testsuite/ChangeLog ++++ b/gcc/testsuite/ChangeLog +@@ -1,3 +1,7 @@ ++2016-04-28 Andrew Burgess ++ ++ * gcc.target/arc/nps400-1.c: New file. ++ + 2016-04-28 Joern Rennecke + Andrew Burgess + +diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c +new file mode 100644 +index 000000000000..f3d62718bb07 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/nps400-1.c +@@ -0,0 +1,23 @@ ++/* { dg-do compile } */ ++/* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */ ++ ++enum npsdp_mem_space_type { ++ NPSDP_EXTERNAL_MS = 1 ++}; ++struct npsdp_ext_addr { ++ struct { ++ struct { ++ enum npsdp_mem_space_type mem_type : 1; ++ unsigned msid : 5; ++ }; ++ }; ++ char user_space[]; ++} a; ++char b; ++void fn1() { ++ ((struct npsdp_ext_addr *)a.user_space)->mem_type = NPSDP_EXTERNAL_MS; ++ ((struct npsdp_ext_addr *)a.user_space)->msid = ++ ((struct npsdp_ext_addr *)a.user_space)->mem_type ? 1 : 10; ++ while (b) ++ ; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0013-ARC-Fix-unwanted-match-for-sign-extend-16-bit-consta.patch b/toolchain/gcc/patches/6.3.0/0013-ARC-Fix-unwanted-match-for-sign-extend-16-bit-consta.patch new file mode 100644 index 0000000..0df4a88 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0013-ARC-Fix-unwanted-match-for-sign-extend-16-bit-consta.patch @@ -0,0 +1,170 @@ +From 7d71e25d0b400d87b1bd55849d1a2016fed1cafe Mon Sep 17 00:00:00 2001 +From: claziss +Date: Fri, 29 Apr 2016 08:39:22 +0000 +Subject: [PATCH 13/89] [ARC] Fix unwanted match for sign extend 16-bit + constant. + +The combine pass may conclude umulhisi3_imm pattern can accept also sign +extended 16-bit constants. This patch prohibits the combine in considering +this pattern as suitable. + +gcc/ +2016-04-29 Claudiu Zissulescu + + * config/arc/arc.h (UNSIGNED_INT12, UNSIGNED_INT16): Define. + * config/arc/arc.md (umulhisi3): Use arc_short_operand predicate. + (umulhisi3_imm): Update predicates and constraint letters. + (umulhisi3_reg): Declare instruction as commutative. + * config/arc/constraints.md (J12, J16): New constraints. + * config/arc/predicates.md (short_unsigned_const_operand): New + predicate. + (arc_short_operand): Likewise. + * testsuite/gcc.target/arc/umulsihi3_z.c: New file. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235623 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 12 ++++++++++++ + gcc/config/arc/arc.h | 2 ++ + gcc/config/arc/arc.md | 10 +++++----- + gcc/config/arc/constraints.md | 12 ++++++++++++ + gcc/config/arc/predicates.md | 8 ++++++++ + gcc/testsuite/gcc.target/arc/umulsihi3_z.c | 23 +++++++++++++++++++++++ + 6 files changed, 62 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/umulsihi3_z.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 0d4a3c076c27..e4c13b6be1e5 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,15 @@ ++2016-04-29 Claudiu Zissulescu ++ ++ * config/arc/arc.h (UNSIGNED_INT12, UNSIGNED_INT16): Define. ++ * config/arc/arc.md (umulhisi3): Use arc_short_operand predicate. ++ (umulhisi3_imm): Update predicates and constraint letters. ++ (umulhisi3_reg): Declare instruction as commutative. ++ * config/arc/constraints.md (J12, J16): New constraints. ++ * config/arc/predicates.md (short_unsigned_const_operand): New ++ predicate. ++ (arc_short_operand): Likewise. ++ * testsuite/gcc.target/arc/umulsihi3_z.c: New file. ++ + 2016-04-28 Joern Rennecke + Andrew Burgess + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 4235eabc96d3..bc14d11ab1f9 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -815,6 +815,8 @@ extern enum reg_class arc_regno_reg_class[]; + #define UNSIGNED_INT6(X) ((unsigned) (X) < 0x40) + #define UNSIGNED_INT7(X) ((unsigned) (X) < 0x80) + #define UNSIGNED_INT8(X) ((unsigned) (X) < 0x100) ++#define UNSIGNED_INT12(X) ((unsigned) (X) < 0x800) ++#define UNSIGNED_INT16(X) ((unsigned) (X) < 0x10000) + #define IS_ONE(X) ((X) == 1) + #define IS_ZERO(X) ((X) == 0) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 7c30eb46e072..d1a9159411da 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -1820,7 +1820,7 @@ + (define_expand "umulhisi3" + [(set (match_operand:SI 0 "register_operand" "") + (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "")) +- (zero_extend:SI (match_operand:HI 2 "nonmemory_operand" ""))))] ++ (zero_extend:SI (match_operand:HI 2 "arc_short_operand" ""))))] + "TARGET_MPYW" + "{ + if (CONSTANT_P (operands[2])) +@@ -1832,9 +1832,9 @@ + ) + + (define_insn "umulhisi3_imm" +- [(set (match_operand:SI 0 "register_operand" "=r, r,r, r, r") +- (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " 0, r,0, 0, r")) +- (match_operand:HI 2 "short_const_int_operand" " L, L,I,C16,C16")))] ++ [(set (match_operand:SI 0 "register_operand" "=r, r, r, r, r") ++ (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" "%0, r, 0, 0, r")) ++ (match_operand:HI 2 "short_unsigned_const_operand" " L, L,J12,J16,J16")))] + "TARGET_MPYW" + "mpyuw%? %0,%1,%2" + [(set_attr "length" "4,4,4,8,8") +@@ -1846,7 +1846,7 @@ + + (define_insn "umulhisi3_reg" + [(set (match_operand:SI 0 "register_operand" "=Rcqq, r, r") +- (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " 0, 0, r")) ++ (mult:SI (zero_extend:SI (match_operand:HI 1 "register_operand" " %0, 0, r")) + (zero_extend:SI (match_operand:HI 2 "register_operand" " Rcqq, r, r"))))] + "TARGET_MPYW" + "mpyuw%? %0,%1,%2" +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index f30572c48579..5069d7d9746d 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -499,3 +499,15 @@ + (define_memory_constraint "ATO" + "A memory with only a base register" + (match_operand 0 "mem_noofs_operand")) ++ ++(define_constraint "J12" ++ "@internal ++ An unsigned 12-bit integer constant." ++ (and (match_code "const_int") ++ (match_test "UNSIGNED_INT12 (ival)"))) ++ ++(define_constraint "J16" ++ "@internal ++ An unsigned 16-bit integer constant" ++ (and (match_code "const_int") ++ (match_test "UNSIGNED_INT16 (ival)"))) +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 0d2e217bf9d6..8e4b4b40c543 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -838,3 +838,11 @@ + (ior (match_operand:SI 0 "cmem_address_0") + (match_operand:SI 0 "cmem_address_1") + (match_operand:SI 0 "cmem_address_2"))) ++ ++(define_predicate "short_unsigned_const_operand" ++ (and (match_code "const_int") ++ (match_test "satisfies_constraint_J16 (op)"))) ++ ++(define_predicate "arc_short_operand" ++ (ior (match_test "register_operand (op, mode)") ++ (match_test "short_unsigned_const_operand (op, mode)"))) +diff --git a/gcc/testsuite/gcc.target/arc/umulsihi3_z.c b/gcc/testsuite/gcc.target/arc/umulsihi3_z.c +new file mode 100644 +index 000000000000..cf1c00d806ac +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/umulsihi3_z.c +@@ -0,0 +1,23 @@ ++/* Check if the optimizers are not removing the umulsihi3_imm ++ instruction. */ ++/* { dg-do run } */ ++/* { dg-options "-O2 -fno-inline" } */ ++ ++#include ++ ++static int32_t test (int16_t reg_val) ++{ ++ int32_t x = (reg_val & 0xf) * 62500; ++ return x; ++} ++ ++int main (void) ++{ ++ volatile int32_t x = 0xc172; ++ x = test (x); ++ ++ if (x != 0x0001e848) ++ __builtin_abort (); ++ return 0; ++} ++ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0014-ARC-Fix-obsolete-constraint.patch b/toolchain/gcc/patches/6.3.0/0014-ARC-Fix-obsolete-constraint.patch new file mode 100644 index 0000000..9706a91 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0014-ARC-Fix-obsolete-constraint.patch @@ -0,0 +1,72 @@ +From 2825bab71dba8b30e45d7cb1b5885b6107a70a19 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Fri, 29 Apr 2016 10:11:25 +0000 +Subject: [PATCH 14/89] [ARC] Fix obsolete constraint. + +include/ +2016-04-29 Claudiu Zissulescu + + * longlong.h (add_ssaaaa): Replace obsolete 'J' constraint with + 'Cal' constraint. + (sub_ddmmss): Likewise. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235631 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + include/ChangeLog | 6 ++++++ + include/longlong.h | 12 ++++++------ + 2 files changed, 12 insertions(+), 6 deletions(-) + +diff --git a/include/ChangeLog b/include/ChangeLog +index 72a60fd48a95..429da9da7139 100644 +--- a/include/ChangeLog ++++ b/include/ChangeLog +@@ -1,3 +1,9 @@ ++2016-04-29 Claudiu Zissulescu ++ ++ * longlong.h (add_ssaaaa): Replace obsolete 'J' constraint with ++ 'Cal' constraint. ++ (sub_ddmmss): Likewise. ++ + 2016-12-21 Release Manager + + * GCC 6.3.0 released. +diff --git a/include/longlong.h b/include/longlong.h +index 34ad9b4f5710..03fd2a1ae4c3 100644 +--- a/include/longlong.h ++++ b/include/longlong.h +@@ -197,17 +197,17 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "%r" ((USItype) (ah)), \ +- "rIJ" ((USItype) (bh)), \ ++ "rICal" ((USItype) (bh)), \ + "%r" ((USItype) (al)), \ +- "rIJ" ((USItype) (bl))) ++ "rICal" ((USItype) (bl))) + #define sub_ddmmss(sh, sl, ah, al, bh, bl) \ + __asm__ ("sub.f %1, %4, %5\n\tsbc %0, %2, %3" \ + : "=r" ((USItype) (sh)), \ + "=&r" ((USItype) (sl)) \ + : "r" ((USItype) (ah)), \ +- "rIJ" ((USItype) (bh)), \ ++ "rICal" ((USItype) (bh)), \ + "r" ((USItype) (al)), \ +- "rIJ" ((USItype) (bl))) ++ "rICal" ((USItype) (bl))) + + #define __umulsidi3(u,v) ((UDItype)(USItype)u*(USItype)v) + #ifdef __ARC_NORM__ +@@ -221,8 +221,8 @@ extern UDItype __udiv_qrnnd (UDItype *, UDItype, UDItype, UDItype); + } \ + while (0) + #define COUNT_LEADING_ZEROS_0 32 +-#endif +-#endif ++#endif /* __ARC_NORM__ */ ++#endif /* __arc__ */ + + #if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \ + && W_TYPE_SIZE == 32 +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0015-ARC-Handle-FPX-NaN-within-optimized-floating-point-l.patch b/toolchain/gcc/patches/6.3.0/0015-ARC-Handle-FPX-NaN-within-optimized-floating-point-l.patch new file mode 100644 index 0000000..f9cc3cc --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0015-ARC-Handle-FPX-NaN-within-optimized-floating-point-l.patch @@ -0,0 +1,133 @@ +From d633237810ddded2096a5d56981e55ae49e89614 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Fri, 29 Apr 2016 10:49:26 +0000 +Subject: [PATCH 15/89] [ARC] Handle FPX NaN within optimized floating point + library. + +gcc/ +2016-04-29 Claudiu Zissulescu + + * testsuite/gcc.target/arc/ieee_eq.c: New test. + +libgcc/ +2016-04-29 Claudiu Zissulescu + + * config/arc/ieee-754/eqdf2.S: Handle FPX NaN. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235633 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 4 +++ + gcc/testsuite/gcc.target/arc/ieee_eq.c | 47 ++++++++++++++++++++++++++++++++++ + libgcc/ChangeLog | 4 +++ + libgcc/config/arc/ieee-754/eqdf2.S | 15 +++++++---- + 4 files changed, 65 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/ieee_eq.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index e4c13b6be1e5..55d8f825478f 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,9 @@ + 2016-04-29 Claudiu Zissulescu + ++ * testsuite/gcc.target/arc/ieee_eq.c: New test. ++ ++2016-04-29 Claudiu Zissulescu ++ + * config/arc/arc.h (UNSIGNED_INT12, UNSIGNED_INT16): Define. + * config/arc/arc.md (umulhisi3): Use arc_short_operand predicate. + (umulhisi3_imm): Update predicates and constraint letters. +diff --git a/gcc/testsuite/gcc.target/arc/ieee_eq.c b/gcc/testsuite/gcc.target/arc/ieee_eq.c +new file mode 100644 +index 000000000000..70aebad063bc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/ieee_eq.c +@@ -0,0 +1,47 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++ ++#include ++#include ++ ++#define TEST_EQ(TYPE,X,Y,RES) \ ++ do { \ ++ volatile TYPE a, b; \ ++ a = (TYPE) X; \ ++ b = (TYPE) Y; \ ++ if ((a == b) != RES) \ ++ { \ ++ printf ("Runtime computation error @%d. %g " \ ++ "!= %g\n", __LINE__, a, b); \ ++ error = 1; \ ++ } \ ++ } while (0) ++ ++#ifndef __HS__ ++/* Special type of NaN found when using double FPX instructions. */ ++static const unsigned long long __nan = 0x7FF0000080000000ULL; ++# define W (*(double *) &__nan) ++#else ++# define W __builtin_nan ("") ++#endif ++ ++#define Q __builtin_nan ("") ++#define H __builtin_inf () ++ ++int main (void) ++{ ++ int error = 0; ++ ++ TEST_EQ (double, 1, 1, 1); ++ TEST_EQ (double, 1, 2, 0); ++ TEST_EQ (double, W, W, 0); ++ TEST_EQ (double, Q, Q, 0); ++ TEST_EQ (double, __DBL_MAX__, __DBL_MAX__, 1); ++ TEST_EQ (double, __DBL_MIN__, __DBL_MIN__, 1); ++ TEST_EQ (double, H, H, 1); ++ ++ if (error) ++ __builtin_abort (); ++ ++ return 0; ++} +diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog +index 0993d6226cd2..ac1ab461a8bb 100644 +--- a/libgcc/ChangeLog ++++ b/libgcc/ChangeLog +@@ -1,3 +1,7 @@ ++2016-04-29 Claudiu Zissulescu ++ ++ * config/arc/ieee-754/eqdf2.S: Handle FPX NaN. ++ + 2016-04-28 Claudiu Zissulescu + Joern Rennecke + +diff --git a/libgcc/config/arc/ieee-754/eqdf2.S b/libgcc/config/arc/ieee-754/eqdf2.S +index bc7d88e838da..7e80ef52b2a8 100644 +--- a/libgcc/config/arc/ieee-754/eqdf2.S ++++ b/libgcc/config/arc/ieee-754/eqdf2.S +@@ -58,11 +58,16 @@ __eqdf2: + well predictable (as seen from the branch predictor). */ + __eqdf2: + brne.d DBL0H,DBL1H,.Lhighdiff +- bmsk r12,DBL0H,20 +-#ifdef DPFP_COMPAT +- or.f 0,DBL0L,DBL1L +- bset.ne r12,r12,21 +-#endif /* DPFP_COMPAT */ ++#ifndef __HS__ ++ /* The next two instructions are required to recognize the FPX ++ NaN, which has a pattern like this: 0x7ff0_0000_8000_0000, as ++ oposite to 0x7ff8_0000_0000_0000. */ ++ or.f 0,DBL0L,DBL1L ++ mov_s r12,0x00200000 ++ bset.ne r12,r12,0 ++#else ++ bmsk r12,DBL0H,20 ++#endif /* __HS__ */ + add1.f r12,r12,DBL0H /* set c iff NaN; also, clear z if NaN. */ + j_s.d [blink] + cmp.cc DBL0L,DBL1L +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0016-2016-04-29-Andrew-Burgess-andrew.burgess-embecosm.co.patch b/toolchain/gcc/patches/6.3.0/0016-2016-04-29-Andrew-Burgess-andrew.burgess-embecosm.co.patch new file mode 100644 index 0000000..41f0860 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0016-2016-04-29-Andrew-Burgess-andrew.burgess-embecosm.co.patch @@ -0,0 +1,123 @@ +From 9eb16132cfed12dc87c50c02e58db1554607b92a Mon Sep 17 00:00:00 2001 +From: amylaar +Date: Fri, 29 Apr 2016 12:07:31 +0000 +Subject: [PATCH 16/89] 2016-04-29 Andrew Burgess + + + * config/arc/arc.md (*loadqi_update): Replace use of 'rI' + constraint with 'rCm2' constraints to limit possible immediate + size. + (*load_zeroextendqisi_update): Likewise. + (*load_signextendqisi_update): Likewise. + (*loadhi_update): Likewise. + (*load_zeroextendhisi_update): Likewise. + (*load_signextendhisi_update): Likewise. + (*loadsi_update): Likewise. + (*loadsf_update): Likewise. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235636 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 13 +++++++++++++ + gcc/config/arc/arc.md | 16 ++++++++-------- + 2 files changed, 21 insertions(+), 8 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 55d8f825478f..2db7b54b57a8 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,16 @@ ++2016-04-29 Andrew Burgess ++ ++ * config/arc/arc.md (*loadqi_update): Replace use of 'rI' ++ constraint with 'rCm2' constraints to limit possible immediate ++ size. ++ (*load_zeroextendqisi_update): Likewise. ++ (*load_signextendqisi_update): Likewise. ++ (*loadhi_update): Likewise. ++ (*load_zeroextendhisi_update): Likewise. ++ (*load_signextendhisi_update): Likewise. ++ (*loadsi_update): Likewise. ++ (*loadsf_update): Likewise. ++ + 2016-04-29 Claudiu Zissulescu + + * testsuite/gcc.target/arc/ieee_eq.c: New test. +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index d1a9159411da..c61107f4b416 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -1254,7 +1254,7 @@ + [(set (match_operand:QI 3 "dest_reg_operand" "=r,r") + (match_operator:QI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) + (set (match_operand:SI 0 "dest_reg_operand" "=r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1266,7 +1266,7 @@ + [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") + (zero_extend:SI (match_operator:QI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) + (set (match_operand:SI 0 "dest_reg_operand" "=r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1278,7 +1278,7 @@ + [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") + (sign_extend:SI (match_operator:QI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) + (set (match_operand:SI 0 "dest_reg_operand" "=r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1304,7 +1304,7 @@ + [(set (match_operand:HI 3 "dest_reg_operand" "=r,r") + (match_operator:HI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) + (set (match_operand:SI 0 "dest_reg_operand" "=w,w") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1316,7 +1316,7 @@ + [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") + (zero_extend:SI (match_operator:HI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) + (set (match_operand:SI 0 "dest_reg_operand" "=r,r") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1329,7 +1329,7 @@ + [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") + (sign_extend:SI (match_operator:HI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))]))) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))]))) + (set (match_operand:SI 0 "dest_reg_operand" "=w,w") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1354,7 +1354,7 @@ + [(set (match_operand:SI 3 "dest_reg_operand" "=r,r") + (match_operator:SI 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) + (set (match_operand:SI 0 "dest_reg_operand" "=w,w") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +@@ -1378,7 +1378,7 @@ + [(set (match_operand:SF 3 "dest_reg_operand" "=r,r") + (match_operator:SF 4 "any_mem_operand" + [(plus:SI (match_operand:SI 1 "register_operand" "0,0") +- (match_operand:SI 2 "nonmemory_operand" "rI,Cal"))])) ++ (match_operand:SI 2 "nonmemory_operand" "rCm2,Cal"))])) + (set (match_operand:SI 0 "dest_reg_operand" "=w,w") + (plus:SI (match_dup 1) (match_dup 2)))] + "" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0017-ARC-Add-new-ARCv2-instructions.patch b/toolchain/gcc/patches/6.3.0/0017-ARC-Add-new-ARCv2-instructions.patch new file mode 100644 index 0000000..f70d026 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0017-ARC-Add-new-ARCv2-instructions.patch @@ -0,0 +1,785 @@ +From a2e3ff8463164c3c530d92a691e27b522289dd5b Mon Sep 17 00:00:00 2001 +From: claziss +Date: Mon, 2 May 2016 08:54:34 +0000 +Subject: [PATCH 17/89] [ARC] Add new ARCv2 instructions. + +gcc/ +2016-05-02 Claudiu Zissulescu + + * config/arc/arc-protos.h (compact_memory_operand_p): Declare. + * config/arc/arc.c (arc_output_commutative_cond_exec): Consider + bmaskn instruction. + (arc_dwarf_register_span): Remove enum keyword. + (compact_memory_operand_p): New function. + * config/arc/arc.h (reg_class): Add code density register classes. + (REG_CLASS_NAMES): Likewise. + (REG_CLASS_CONTENTS): Likewise. + * config/arc/arc.md (*movqi_insn): Add code density instructions. + (*movhi_insn, *movsi_insn, *movsf_insn): Likewise. + (*extendhisi2_i, andsi3_i, cmpsi_cc_insn_mixed): Likewise. + (*cmpsi_cc_c_insn, *movsi_ne): Likewise. + * config/arc/constraints.md (C2p, Uts, Cm1, Cm3, Ucd): New + constraints. + (h, Rcd, Rsd, Rzd): New register constraints. + (T): Use compact_memory_operand_p function. + * config/arc/predicates.md (compact_load_memory_operand): Remove. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235707 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 20 ++++++ + gcc/config/arc/arc-protos.h | 2 +- + gcc/config/arc/arc.c | 146 +++++++++++++++++++++++++++++++++++++++ + gcc/config/arc/arc.h | 9 +++ + gcc/config/arc/arc.md | 154 ++++++++++++++++++++++++------------------ + gcc/config/arc/constraints.md | 61 ++++++++++++++++- + gcc/config/arc/predicates.md | 89 ------------------------ + 7 files changed, 324 insertions(+), 157 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 2db7b54b57a8..cedbe6eb44f2 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,23 @@ ++2016-05-02 Claudiu Zissulescu ++ ++ * config/arc/arc-protos.h (compact_memory_operand_p): Declare. ++ * config/arc/arc.c (arc_output_commutative_cond_exec): Consider ++ bmaskn instruction. ++ (arc_dwarf_register_span): Remove enum keyword. ++ (compact_memory_operand_p): New function. ++ * config/arc/arc.h (reg_class): Add code density register classes. ++ (REG_CLASS_NAMES): Likewise. ++ (REG_CLASS_CONTENTS): Likewise. ++ * config/arc/arc.md (*movqi_insn): Add code density instructions. ++ (*movhi_insn, *movsi_insn, *movsf_insn): Likewise. ++ (*extendhisi2_i, andsi3_i, cmpsi_cc_insn_mixed): Likewise. ++ (*cmpsi_cc_c_insn, *movsi_ne): Likewise. ++ * config/arc/constraints.md (C2p, Uts, Cm1, Cm3, Ucd): New ++ constraints. ++ (h, Rcd, Rsd, Rzd): New register constraints. ++ (T): Use compact_memory_operand_p function. ++ * config/arc/predicates.md (compact_load_memory_operand): Remove. ++ + 2016-04-29 Andrew Burgess + + * config/arc/arc.md (*loadqi_update): Replace use of 'rI' +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 3bf28a088bd9..8630e2d84daa 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -44,7 +44,7 @@ extern void emit_shift (enum rtx_code, rtx, rtx, rtx); + extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); + extern void arc_split_compare_and_swap (rtx *); + extern void arc_expand_compare_and_swap (rtx *); +- ++extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool); + #endif /* RTX_CODE */ + + #ifdef TREE_CODE +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index dfaea7b92412..a54fddb45d32 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -7389,6 +7389,11 @@ arc_output_commutative_cond_exec (rtx *operands, bool output_p) + case AND: + if (satisfies_constraint_C1p (operands[2])) + pat = "bmsk%? %0,%1,%Z2"; ++ else if (satisfies_constraint_C2p (operands[2])) ++ { ++ operands[2] = GEN_INT ((~INTVAL (operands[2]))); ++ pat = "bmskn%? %0,%1,%Z2"; ++ } + else if (satisfies_constraint_Ccp (operands[2])) + pat = "bclr%? %0,%1,%M2"; + else if (satisfies_constraint_CnL (operands[2])) +@@ -9859,12 +9864,153 @@ arc_dwarf_register_span (rtx rtl) + + /* We can't inline this in INSN_REFERENCES_ARE_DELAYED because + resource.h doesn't include the required header files. */ ++ + bool + insn_is_tls_gd_dispatch (rtx_insn *insn) + { + return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch; + } + ++/* Return true if OP is an acceptable memory operand for ARCompact ++ 16-bit load instructions of MODE. ++ ++ AV2SHORT: TRUE if address needs to fit into the new ARCv2 short ++ non scaled instructions. ++ ++ SCALED: TRUE if address can be scaled. */ ++ ++bool ++compact_memory_operand_p (rtx op, machine_mode mode, ++ bool av2short, bool scaled) ++{ ++ rtx addr, plus0, plus1; ++ int size, off; ++ ++ /* Eliminate non-memory operations. */ ++ if (GET_CODE (op) != MEM) ++ return 0; ++ ++ /* .di instructions have no 16-bit form. */ ++ if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) ++ return false; ++ ++ if (mode == VOIDmode) ++ mode = GET_MODE (op); ++ ++ size = GET_MODE_SIZE (mode); ++ ++ /* dword operations really put out 2 instructions, so eliminate ++ them. */ ++ if (size > UNITS_PER_WORD) ++ return false; ++ ++ /* Decode the address now. */ ++ addr = XEXP (op, 0); ++ switch (GET_CODE (addr)) ++ { ++ case REG: ++ return (REGNO (addr) >= FIRST_PSEUDO_REGISTER ++ || COMPACT_GP_REG_P (REGNO (addr)) ++ || (SP_REG_P (REGNO (addr)) && (size != 2))); ++ case PLUS: ++ plus0 = XEXP (addr, 0); ++ plus1 = XEXP (addr, 1); ++ ++ if ((GET_CODE (plus0) == REG) ++ && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) ++ || COMPACT_GP_REG_P (REGNO (plus0))) ++ && ((GET_CODE (plus1) == REG) ++ && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) ++ || COMPACT_GP_REG_P (REGNO (plus1))))) ++ { ++ return !av2short; ++ } ++ ++ if ((GET_CODE (plus0) == REG) ++ && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) ++ || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short) ++ || (IN_RANGE (REGNO (plus0), 0, 31) && av2short)) ++ && (GET_CODE (plus1) == CONST_INT)) ++ { ++ bool valid = false; ++ ++ off = INTVAL (plus1); ++ ++ /* Negative offset is not supported in 16-bit load/store insns. */ ++ if (off < 0) ++ return 0; ++ ++ /* Only u5 immediates allowed in code density instructions. */ ++ if (av2short) ++ { ++ switch (size) ++ { ++ case 1: ++ return false; ++ case 2: ++ /* This is an ldh_s.x instruction, check the u6 ++ immediate. */ ++ if (COMPACT_GP_REG_P (REGNO (plus0))) ++ valid = true; ++ break; ++ case 4: ++ /* Only u5 immediates allowed in 32bit access code ++ density instructions. */ ++ if (REGNO (plus0) <= 31) ++ return ((off < 32) && (off % 4 == 0)); ++ break; ++ default: ++ return false; ++ } ++ } ++ else ++ if (COMPACT_GP_REG_P (REGNO (plus0))) ++ valid = true; ++ ++ if (valid) ++ { ++ ++ switch (size) ++ { ++ case 1: ++ return (off < 32); ++ case 2: ++ /* The 6-bit constant get shifted to fit the real ++ 5-bits field. Check also for the alignment. */ ++ return ((off < 64) && (off % 2 == 0)); ++ case 4: ++ return ((off < 128) && (off % 4 == 0)); ++ default: ++ return false; ++ } ++ } ++ } ++ ++ if (REG_P (plus0) && CONST_INT_P (plus1) ++ && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) ++ || SP_REG_P (REGNO (plus0))) ++ && !av2short) ++ { ++ off = INTVAL (plus1); ++ return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); ++ } ++ ++ if ((GET_CODE (plus0) == MULT) ++ && (GET_CODE (XEXP (plus0, 0)) == REG) ++ && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER) ++ || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0)))) ++ && (GET_CODE (plus1) == REG) ++ && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) ++ || COMPACT_GP_REG_P (REGNO (plus1)))) ++ return scaled; ++ default: ++ break ; ++ /* TODO: 'gp' and 'pcl' are to supported as base address operand ++ for 16-bit load instructions. */ ++ } ++ return false; ++} ++ + struct gcc_target targetm = TARGET_INITIALIZER; + + #include "gt-arc.h" +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index bc14d11ab1f9..f6b85ea7e51b 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -674,6 +674,9 @@ enum reg_class + WRITABLE_CORE_REGS, /* 'w' */ + CHEAP_CORE_REGS, /* 'c' */ + ALL_CORE_REGS, /* 'Rac' */ ++ R0R3_CD_REGS, /* 'Rcd' */ ++ R0R1_CD_REGS, /* 'Rsd' */ ++ AC16_H_REGS, /* 'h' */ + ALL_REGS, + LIM_REG_CLASSES + }; +@@ -700,6 +703,9 @@ enum reg_class + "MPY_WRITABLE_CORE_REGS", \ + "WRITABLE_CORE_REGS", \ + "CHEAP_CORE_REGS", \ ++ "R0R3_CD_REGS", \ ++ "R0R1_CD_REGS", \ ++ "AC16_H_REGS", \ + "ALL_CORE_REGS", \ + "ALL_REGS" \ + } +@@ -732,6 +738,9 @@ enum reg_class + {0xffffffff, 0xd0000000, 0x00000000, 0x00000000, 0x00000000}, /* 'w', r0-r31, r60 */ \ + {0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'c', r0-r60, ap, pcl */ \ + {0xffffffff, 0xdfffffff, 0x00000000, 0x00000000, 0x00000000}, /* 'Rac', r0-r60, ap, pcl */ \ ++ {0x0000000f, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rcd', r0-r3 */ \ ++ {0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'Rsd', r0-r1 */ \ ++ {0x9fffffff, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, /* 'h', r0-28, r30 */ \ + {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x0003ffff} /* All Registers */ \ + } + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index c61107f4b416..85e54587d99d 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -620,14 +620,15 @@ + ; The iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + (define_insn "*movqi_insn" +- [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,w,Rcq,S,!*x,r,r,Ucm,m,???m") +- (match_operand:QI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] ++ [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w, w,Rcq, S,!*x, r,r, Ucm,m,???m") ++ (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] + "register_operand (operands[0], QImode) + || register_operand (operands[1], QImode)" + "@ + mov%? %0,%1%& + mov%? %0,%1%& + mov%? %0,%1%& ++ mov%? %0,%1%& + mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%1 +@@ -640,10 +641,10 @@ + xstb%U0 %1,%0 + stb%U0%V0 %1,%0 + stb%U0%V0 %1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,true,true,true,false,false,false,false,false") +- (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,false,true,true,true,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*")]) + + (define_expand "movhi" + [(set (match_operand:HI 0 "move_dest_operand" "") +@@ -652,8 +653,8 @@ + "if (prepare_move_operands (operands, HImode)) DONE;") + + (define_insn "*movhi_insn" +- [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,???w,Rcq#q,w,Rcq,S,r,r,Ucm,m,???m,VUsc") +- (match_operand:HI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,?Rac,?i,?i,T,Rcq,Ucm,m,?Rac,c,?Rac,i"))] ++ [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w,Rcq#q, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc") ++ (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac, ?i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))] + "register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || (CONSTANT_P (operands[1]) +@@ -665,6 +666,7 @@ + mov%? %0,%1%& + mov%? %0,%1%& + mov%? %0,%1%& ++ mov%? %0,%1%& + mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%1 +@@ -677,11 +679,12 @@ + xst%_%U0 %1,%0 + st%_%U0%V0 %1,%0 + st%_%U0%V0 %1,%0 ++ st%_%U0%V0 %S1,%0 + st%_%U0%V0 %S1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false") +- (set_attr "predicable" "yes,no,yes,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")]) + + (define_expand "movsi" + [(set (match_operand:SI 0 "move_dest_operand" "") +@@ -699,9 +702,9 @@ + ; the iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . +-(define_insn "*movsi_insn" +- [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q,w,w,w,w,w,w,w,???w,?w,w,Rcq#q,w,Rcq,S,Us<,RcqRck,!*x,r,r,Ucm,m,???m,VUsc") +- (match_operand:SI 1 "move_src_operand" "cL,cP,Rcq#q,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb,?Cal,?Cal,T,Rcq,RcqRck,Us>,Usd,Ucm,m,w,c,?Rac,C32"))] ++(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ++ [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") ++ (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || (CONSTANT_P (operands[1]) +@@ -713,35 +716,40 @@ + mov%? %0,%1%& ;0 + mov%? %0,%1%& ;1 + mov%? %0,%1%& ;2 +- mov%? %0,%1 ;3 ++ mov%? %0,%1%& ;3 + mov%? %0,%1 ;4 +- ror %0,((%1*2+1) & 0x3f) ;5 +- movl.cl %0,%1 ;6 +- movh.cl %0,%L1>>16 ;7 ++ mov%? %0,%1 ;5 ++ ror %0,((%1*2+1) & 0x3f) ;6 ++ movl.cl %0,%1 ;7 ++ movh.cl %0,%L1>>16 ;8 + * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\"; +- mov%? %0,%1 ;9 +- add %0,%S1 ;10 ++ mov%? %0,%1 ;10 ++ add %0,%S1 ;11 + * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; +- mov%? %0,%S1%& ;12 +- mov%? %0,%S1 ;13 +- ld%? %0,%1%& ;14 +- st%? %1,%0%& ;15 ++ mov%? %0,%S1%& ;13 ++ mov%? %0,%S1 ;14 ++ ld%? %0,%1%& ;15 ++ st%? %1,%0%& ;16 + * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); + * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); +- ld%? %0,%1%& ;18 +- xld%U1 %0,%1 ;19 +- ld%U1%V1 %0,%1 ;20 +- xst%U0 %1,%0 ;21 +- st%U0%V0 %1,%0 ;22 +- st%U0%V0 %1,%0 ;23 +- st%U0%V0 %S1,%0 ;24" +- [(set_attr "type" "move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,store,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false") ++ ld%? %0,%1%& ;19 ++ xld%U1 %0,%1 ;20 ++ ld%? %0,%1%& ;21 ++ ld%? %0,%1%& ;22 ++ ld%U1%V1 %0,%1 ;23 ++ xst%U0 %1,%0 ;24 ++ st%? %1,%0%& ;25 ++ st%U0%V0 %1,%0 ;26 ++ st%U0%V0 %1,%0 ;27 ++ st%U0%V0 %1,%0 ;28 ++ st%U0%V0 %S1,%0 ;29" ++ [(set_attr "type" "move,move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,load,load,store,store,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false") + ; Use default length for iscompact to allow for COND_EXEC. But set length + ; of Crr to 4. +- (set_attr "length" "*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,8") +- (set_attr "predicable" "yes,no,yes,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ (set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8") ++ (set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) + + ;; Sometimes generated by the epilogue code. We don't want to + ;; recognize these addresses in general, because the limm is costly, +@@ -1136,17 +1144,19 @@ + "if (prepare_move_operands (operands, SFmode)) DONE;") + + (define_insn "*movsf_insn" +- [(set (match_operand:SF 0 "move_dest_operand" "=w,w,r,m") +- (match_operand:SF 1 "move_src_operand" "c,E,m,c"))] ++ [(set (match_operand:SF 0 "move_dest_operand" "=h,w,w,r,m") ++ (match_operand:SF 1 "move_src_operand" "hCm1,c,E,m,c"))] + "register_operand (operands[0], SFmode) + || register_operand (operands[1], SFmode)" + "@ + mov%? %0,%1 ++ mov%? %0,%1 + mov%? %0,%1 ; %A1 + ld%U1%V1 %0,%1 + st%U0%V0 %1,%0" +- [(set_attr "type" "move,move,load,store") +- (set_attr "predicable" "yes,yes,no,no")]) ++ [(set_attr "type" "move,move,move,load,store") ++ (set_attr "predicable" "no,yes,yes,no,no") ++ (set_attr "iscompact" "true,false,false,false,false")]) + + (define_expand "movdf" + [(set (match_operand:DF 0 "nonimmediate_operand" "") +@@ -1664,17 +1674,18 @@ + ) + + (define_insn "*extendhisi2_i" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,r,r") +- (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Uex,m")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w,Rcq,r,r") ++ (sign_extend:SI (match_operand:HI 1 "nonvol_nonimm_operand" "Rcqq,c,Ucd,Uex,m")))] + "" + "@ + sex%_%? %0,%1%& + sex%_ %0,%1 ++ ldh%?.x %0,%1%& + ld%_.x%U1%V1 %0,%1 + ld%_.x%U1%V1 %0,%1" +- [(set_attr "type" "unary,unary,load,load") +- (set_attr "iscompact" "true,false,false,false") +- (set_attr "length" "*,*,4,8")]) ++ [(set_attr "type" "unary,unary,load,load,load") ++ (set_attr "iscompact" "true,false,true,false,false") ++ (set_attr "length" "*,*,*,4,8")]) + + (define_expand "extendhisi2" + [(set (match_operand:SI 0 "dest_reg_operand" "") +@@ -3041,9 +3052,9 @@ + operands[1] = arc_rewrite_small_data (operands[1]);") + + (define_insn "andsi3_i" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw,Rcw,Rcw,Rcw,Rcw,w,w,w,w,Rrq,w,Rcw,w,W") +- (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq,0,0,Rcqq,0,c,0,0,0,0,c,c,c,c,Rrq,0,0,c,o") +- (match_operand:SI 2 "nonmemory_operand" "Rcqq,0,C1p,Ccp,Cux,cL,0,C1p,Ccp,CnL,I,Lc,C1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcq,Rcqq,Rcqq,Rcqq,Rcw,Rcw, Rcw,Rcw,Rcw,Rcw, w, w, w, w,Rrq,w,Rcw, w,W") ++ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,Rcq, 0, 0,Rcqq, 0, c, 0, 0, 0, 0, c, c, c, c,Rrq,0, 0, c,o") ++ (match_operand:SI 2 "nonmemory_operand" "Rcqq, 0, C1p, Ccp, Cux, cL, 0,C2pC1p,Ccp,CnL, I,Lc,C2pC1p,Ccp,CnL,Cbf,I,Cal,Cal,Cux")))] + "(register_operand (operands[1], SImode) + && nonmemory_operand (operands[2], SImode)) + || (memory_operand (operands[1], SImode) +@@ -3055,8 +3066,18 @@ + return "and%? %0,%1,%2%&"; + case 1: case 6: + return "and%? %0,%2,%1%&"; +- case 2: case 7: case 12: ++ case 2: + return "bmsk%? %0,%1,%Z2%&"; ++ case 7: case 12: ++ if (satisfies_constraint_C2p (operands[2])) ++ { ++ operands[2] = GEN_INT ((~INTVAL (operands[2]))); ++ return "bmskn%? %0,%1,%Z2%&"; ++ } ++ else ++ { ++ return "bmsk%? %0,%1,%Z2%&"; ++ } + case 3: case 8: case 13: + return "bclr%? %0,%1,%M2%&"; + case 4: +@@ -3368,15 +3389,15 @@ + ;; modifed cc user if second, but not first operand is a compact register. + (define_insn "cmpsi_cc_insn_mixed" + [(set (reg:CC CC_REG) +- (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,c,c, qRcq, c") +- (match_operand:SI 1 "nonmemory_operand" "cO,cI,cL, Cal, Cal")))] ++ (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, h, c, c,qRcq,c") ++ (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI,cL, Cal,Cal")))] + "" + "cmp%? %0,%B1%&" + [(set_attr "type" "compare") +- (set_attr "iscompact" "true,false,false,true_limm,false") +- (set_attr "predicable" "no,no,yes,no,yes") ++ (set_attr "iscompact" "true,true,false,false,true_limm,false") ++ (set_attr "predicable" "no,no,no,yes,no,yes") + (set_attr "cond" "set") +- (set_attr "length" "*,4,4,*,8")]) ++ (set_attr "length" "*,*,4,4,*,8")]) + + (define_insn "*cmpsi_cc_zn_insn" + [(set (reg:CC_ZN CC_REG) +@@ -3452,14 +3473,14 @@ + + (define_insn "*cmpsi_cc_c_insn" + [(set (reg:CC_C CC_REG) +- (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, c,Rcqq, c") +- (match_operand:SI 1 "nonmemory_operand" "cO, cI, Cal,Cal")))] ++ (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, h, c,Rcqq, c") ++ (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI, Cal,Cal")))] + "" + "cmp%? %0,%S1%&" + [(set_attr "type" "compare") +- (set_attr "iscompact" "true,false,true_limm,false") ++ (set_attr "iscompact" "true,true,false,true_limm,false") + (set_attr "cond" "set") +- (set_attr "length" "*,4,*,8")]) ++ (set_attr "length" "*,*,4,*,8")]) + + ;; Next come the scc insns. + +@@ -3552,17 +3573,20 @@ + ; cond_exec patterns + (define_insn "*movsi_ne" + [(cond_exec +- (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc,Rcc,Rcc") (const_int 0)) +- (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,w,w") +- (match_operand:SI 1 "nonmemory_operand" "C_0,Lc,?Cal")))] ++ (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0)) ++ (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w") ++ (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))] + "" + "@ + * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\"; ++ * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; ++ * current_insn_predicate = 0; return \"mov%?.ne %0,%1\"; + mov.ne %0,%1 + mov.ne %0,%S1" +- [(set_attr "type" "cmove,cmove,cmove") +- (set_attr "iscompact" "true,false,false") +- (set_attr "length" "2,4,8")]) ++ [(set_attr "type" "cmove") ++ (set_attr "iscompact" "true,true,true_limm,false,false") ++ (set_attr "length" "2,2,6,4,8") ++ (set_attr "cpu_facility" "*,av2,av2,*,*")]) + + (define_insn "*movsi_cond_exec" + [(cond_exec +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index 5069d7d9746d..b7bf2d39c4e8 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -226,6 +226,14 @@ + (and (match_code "const_int") + (match_test "ival && IS_POWEROF2_P (ival + 1)"))) + ++(define_constraint "C2p" ++ "@internal ++ constant such that (~x)+1 is a power of two, and x < -1" ++ (and (match_code "const_int") ++ (match_test "TARGET_V2 ++ && (ival < -1) ++ && IS_POWEROF2_P ((~ival) + 1)"))) ++ + (define_constraint "C3p" + "@internal + constant int used to select xbfu a,b,u6 instruction. The values accepted are 1 and 2." +@@ -317,7 +325,13 @@ + "@internal + A valid memory operand for ARCompact load instructions" + (and (match_code "mem") +- (match_test "compact_load_memory_operand (op, VOIDmode)"))) ++ (match_test "compact_memory_operand_p (op, mode, false, false)"))) ++ ++(define_memory_constraint "Uts" ++ "@internal ++ A valid memory operand for ARCompact load instructions scaled" ++ (and (match_code "mem") ++ (match_test "compact_memory_operand_p (op, mode, false, TARGET_CODE_DENSITY)"))) + + (define_memory_constraint "S" + "@internal +@@ -340,7 +354,7 @@ + "@internal + A valid _small-data_ memory operand for ARCompact instructions" + (and (match_code "mem") +- (match_test "compact_sda_memory_operand (op, VOIDmode)"))) ++ (match_test "compact_sda_memory_operand (op, VOIDmode)"))) + + (define_memory_constraint "Usc" + "@internal +@@ -483,12 +497,26 @@ + (and (match_code "const_int") + (match_test "IS_ZERO (ival)"))) + ++(define_constraint "Cm1" ++ "@internal ++ Integer signed constant in the interval [-1,6]" ++ (and (match_code "const_int") ++ (match_test "(ival >= -1) && (ival <=6)") ++ (match_test "TARGET_V2"))) ++ + (define_constraint "Cm2" + "@internal + A signed 9-bit integer constant." + (and (match_code "const_int") + (match_test "(ival >= -256) && (ival <=255)"))) + ++(define_constraint "Cm3" ++ "@internal ++ A signed 6-bit integer constant." ++ (and (match_code "const_int") ++ (match_test "(ival >= -32) && (ival <=31)") ++ (match_test "TARGET_V2"))) ++ + (define_constraint "C62" + "@internal + An unsigned 6-bit integer constant, up to 62." +@@ -511,3 +539,32 @@ + An unsigned 16-bit integer constant" + (and (match_code "const_int") + (match_test "UNSIGNED_INT16 (ival)"))) ++ ++; Memory addresses suited for code density load ops ++(define_memory_constraint "Ucd" ++ "@internal ++ A valid memory operand for use with code density load ops" ++ (and (match_code "mem") ++ (match_test "compact_memory_operand_p (op, mode, true, false)") ++ (match_test "TARGET_V2"))) ++ ++(define_register_constraint "h" ++ "TARGET_V2 ? AC16_H_REGS : NO_REGS" ++ "5-bit h register set except @code{r30} and @code{r29}: ++ @code{r0}-@code{r31}, nonfixed core register") ++ ++; Code density registers ++(define_register_constraint "Rcd" ++ "TARGET_CODE_DENSITY ? R0R3_CD_REGS : NO_REGS" ++ "@internal ++ core register @code{r0}-@code{r3}") ++ ++(define_register_constraint "Rsd" ++ "TARGET_CODE_DENSITY ? R0R1_CD_REGS : NO_REGS" ++ "@internal ++ core register @code{r0}-@code{r1}") ++ ++(define_register_constraint "Rzd" ++ "TARGET_CODE_DENSITY ? R0_REGS : NO_REGS" ++ "@internal ++ @code{r0} register for code density instructions.") +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 8e4b4b40c543..f85f931d4601 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -185,95 +185,6 @@ + ) + + ;; Return true if OP is an acceptable memory operand for ARCompact +-;; 16-bit load instructions. +-(define_predicate "compact_load_memory_operand" +- (match_code "mem") +-{ +- rtx addr, plus0, plus1; +- int size, off; +- +- /* Eliminate non-memory operations. */ +- if (GET_CODE (op) != MEM) +- return 0; +- +- /* .di instructions have no 16-bit form. */ +- if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET) +- return 0; +- +- if (mode == VOIDmode) +- mode = GET_MODE (op); +- +- size = GET_MODE_SIZE (mode); +- +- /* dword operations really put out 2 instructions, so eliminate them. */ +- if (size > UNITS_PER_WORD) +- return 0; +- +- /* Decode the address now. */ +- addr = XEXP (op, 0); +- switch (GET_CODE (addr)) +- { +- case REG: +- return (REGNO (addr) >= FIRST_PSEUDO_REGISTER +- || COMPACT_GP_REG_P (REGNO (addr)) +- || (SP_REG_P (REGNO (addr)) && (size != 2))); +- /* Reverting for the moment since ldw_s does not have sp as a valid +- parameter. */ +- case PLUS: +- plus0 = XEXP (addr, 0); +- plus1 = XEXP (addr, 1); +- +- if ((GET_CODE (plus0) == REG) +- && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) +- || COMPACT_GP_REG_P (REGNO (plus0))) +- && ((GET_CODE (plus1) == REG) +- && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER) +- || COMPACT_GP_REG_P (REGNO (plus1))))) +- { +- return 1; +- } +- +- if ((GET_CODE (plus0) == REG) +- && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) +- || COMPACT_GP_REG_P (REGNO (plus0))) +- && (GET_CODE (plus1) == CONST_INT)) +- { +- off = INTVAL (plus1); +- +- /* Negative offset is not supported in 16-bit load/store insns. */ +- if (off < 0) +- return 0; +- +- switch (size) +- { +- case 1: +- return (off < 32); +- case 2: +- return ((off < 64) && (off % 2 == 0)); +- case 4: +- return ((off < 128) && (off % 4 == 0)); +- } +- } +- +- if ((GET_CODE (plus0) == REG) +- && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER) +- || SP_REG_P (REGNO (plus0))) +- && (GET_CODE (plus1) == CONST_INT)) +- { +- off = INTVAL (plus1); +- return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0)); +- } +- default: +- break ; +- /* TODO: 'gp' and 'pcl' are to supported as base address operand +- for 16-bit load instructions. */ +- } +- return 0; +- +-} +-) +- +-;; Return true if OP is an acceptable memory operand for ARCompact + ;; 16-bit store instructions + (define_predicate "compact_store_memory_operand" + (match_code "mem") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0018-Fix-warnings-update-source-code.patch b/toolchain/gcc/patches/6.3.0/0018-Fix-warnings-update-source-code.patch new file mode 100644 index 0000000..f10dd45 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0018-Fix-warnings-update-source-code.patch @@ -0,0 +1,80 @@ +From fab0b35c130abbd2ef3bbf020a443bbbd5d833a7 Mon Sep 17 00:00:00 2001 +From: claziss +Date: Mon, 2 May 2016 09:37:17 +0000 +Subject: [PATCH 18/89] Fix warnings, update source code. + +include/ +2016-05-02 Claudiu Zissulescu + + * config/arc/arc.c (arc_preferred_simd_mode): Remove enum keyword. + (arc_save_restore): Likewise. + (arc_dwarf_register_span): Likewise. + (arc_output_pic_addr_const): Initialize suffix variable. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235718 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 7 +++++++ + gcc/config/arc/arc.c | 9 +++++---- + 2 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index cedbe6eb44f2..4d6016b6cbe6 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,12 @@ + 2016-05-02 Claudiu Zissulescu + ++ * config/arc/arc.c (arc_preferred_simd_mode): Remove enum keyword. ++ (arc_save_restore): Likewise. ++ (arc_dwarf_register_span): Likewise. ++ (arc_output_pic_addr_const): Initialize suffix variable. ++ ++2016-05-02 Claudiu Zissulescu ++ + * config/arc/arc-protos.h (compact_memory_operand_p): Declare. + * config/arc/arc.c (arc_output_commutative_cond_exec): Consider + bmaskn instruction. +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index a54fddb45d32..49edc0a7f657 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -264,8 +264,8 @@ arc_vector_mode_supported_p (machine_mode mode) + + /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */ + +-static enum machine_mode +-arc_preferred_simd_mode (enum machine_mode mode) ++static machine_mode ++arc_preferred_simd_mode (machine_mode mode) + { + switch (mode) + { +@@ -2347,7 +2347,7 @@ arc_save_restore (rtx base_reg, + + for (regno = 0; regno <= 31; regno++) + { +- enum machine_mode mode = SImode; ++ machine_mode mode = SImode; + bool found = false; + + if (TARGET_LL64 +@@ -5124,6 +5124,7 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) + suffix = "@dtpoff"; + break; + default: ++ suffix = "@invalid"; + output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1)); + break; + } +@@ -9847,7 +9848,7 @@ arc_no_speculation_in_delay_slots_p () + static rtx + arc_dwarf_register_span (rtx rtl) + { +- enum machine_mode mode = GET_MODE (rtl); ++ machine_mode mode = GET_MODE (rtl); + unsigned regno; + rtx p; + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0019-ARC-Various-instruction-pattern-fixes.patch b/toolchain/gcc/patches/6.3.0/0019-ARC-Various-instruction-pattern-fixes.patch new file mode 100644 index 0000000..af5d6fc --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0019-ARC-Various-instruction-pattern-fixes.patch @@ -0,0 +1,83 @@ +From 1efcfe036db8f976fe65af2c1c7bcfadc5ba6cbf Mon Sep 17 00:00:00 2001 +From: claziss +Date: Mon, 2 May 2016 11:26:57 +0000 +Subject: [PATCH 19/89] [ARC] Various instruction pattern fixes + +gcc/ +2016-05-02 Claudiu Zissulescu + + * config/arc/arc.md (mulsidi3): Change operand 0 predicate to + register_operand. + (umulsidi3): Likewise. + (indirect_jump): Fix jump instruction assembly patterns. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235749 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 7 +++++++ + gcc/config/arc/arc.md | 19 ++++++++++++------- + 2 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index 4d6016b6cbe6..bfda3c16668f 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,5 +1,12 @@ + 2016-05-02 Claudiu Zissulescu + ++ * config/arc/arc.md (mulsidi3): Change operand 0 predicate to ++ register_operand. ++ (umulsidi3): Likewise. ++ (indirect_jump): Fix jump instruction assembly patterns. ++ ++2016-05-02 Claudiu Zissulescu ++ + * config/arc/arc.c (arc_preferred_simd_mode): Remove enum keyword. + (arc_save_restore): Likewise. + (arc_dwarf_register_span): Likewise. +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 85e54587d99d..a4ee08450a8c 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -2079,9 +2079,9 @@ + (set_attr "cond" "nocond,canuse,nocond,canuse_limm,canuse,nocond")]) + + (define_expand "mulsidi3" +- [(set (match_operand:DI 0 "nonimmediate_operand" "") +- (mult:DI (sign_extend:DI(match_operand:SI 1 "register_operand" "")) +- (sign_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))] ++ [(set (match_operand:DI 0 "register_operand" "") ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) ++ (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] + "TARGET_ANY_MPY" + " + { +@@ -2315,9 +2315,9 @@ + }") + + (define_expand "umulsidi3" +- [(set (match_operand:DI 0 "nonimmediate_operand" "") +- (mult:DI (zero_extend:DI(match_operand:SI 1 "register_operand" "")) +- (zero_extend:DI(match_operand:SI 2 "nonmemory_operand" ""))))] ++ [(set (match_operand:DI 0 "register_operand" "") ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "")) ++ (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] + "" + { + if (TARGET_MPY) +@@ -3809,7 +3809,12 @@ + (define_insn "indirect_jump" + [(set (pc) (match_operand:SI 0 "nonmemory_operand" "L,I,Cal,Rcqq,r"))] + "" +- "j%!%* [%0]%&" ++ "@ ++ j%!%* %0%& ++ j%!%* %0%& ++ j%!%* %0%& ++ j%!%* [%0]%& ++ j%!%* [%0]%&" + [(set_attr "type" "jump") + (set_attr "iscompact" "false,false,false,maybe,false") + (set_attr "cond" "canuse,canuse_limm,canuse,canuse,canuse")]) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0020-ARC-New-CPU-C-define-handler.patch b/toolchain/gcc/patches/6.3.0/0020-ARC-New-CPU-C-define-handler.patch new file mode 100644 index 0000000..f02c5d0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0020-ARC-New-CPU-C-define-handler.patch @@ -0,0 +1,303 @@ +From 47b0081d32fea4a2bdae217281244146133d18c2 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 3 May 2016 11:50:42 +0200 +Subject: [PATCH 20/89] [ARC] New CPU C-define handler. + +gcc/ +2016-05-02 Claudiu Zissulescu + + * config/arc/arc-c.c: New file. + * config/arc/arc-c.def: Likewise. + * config/arc/t-arc: Likewise. + * config.gcc: Include arc-c.o as c and cpp object. + * config/arc/arc-protos.h (arc_cpu_cpp_builtins): Add prototype. + * config/arc/arc.h (TARGET_CPU_CPP_BUILTINS): Use + arc_cpu_cpp_builtins. +--- + gcc/config.gcc | 2 ++ + gcc/config/arc/arc-c.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ + gcc/config/arc/arc-c.def | 68 ++++++++++++++++++++++++++++++++++++++++++++ + gcc/config/arc/arc-protos.h | 1 + + gcc/config/arc/arc.h | 56 +----------------------------------- + gcc/config/arc/t-arc | 29 +++++++++++++++++++ + 6 files changed, 170 insertions(+), 55 deletions(-) + create mode 100644 gcc/config/arc/arc-c.c + create mode 100644 gcc/config/arc/arc-c.def + create mode 100644 gcc/config/arc/t-arc + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 1d5b23f228d2..2cc649e1dc83 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -323,6 +323,8 @@ am33_2.0-*-linux*) + ;; + arc*-*-*) + cpu_type=arc ++ c_target_objs="arc-c.o" ++ cxx_target_objs="arc-c.o" + ;; + arm*-*-*) + cpu_type=arm +diff --git a/gcc/config/arc/arc-c.c b/gcc/config/arc/arc-c.c +new file mode 100644 +index 000000000000..3bf3fd26c2c4 +--- /dev/null ++++ b/gcc/config/arc/arc-c.c +@@ -0,0 +1,69 @@ ++/* Copyright (C) 2016 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 "tree.h" ++#include "tm_p.h" ++#include "cpplib.h" ++#include "c-family/c-common.h" ++#include "target.h" ++ ++#define builtin_define(TXT) cpp_define (pfile, TXT) ++#define builtin_assert(TXT) cpp_assert (pfile, TXT) ++ ++/* Define or undefine macros based on the current target. */ ++ ++static void ++def_or_undef_macro (cpp_reader* pfile, const char *name, bool def_p) ++{ ++ if (def_p) ++ cpp_define (pfile, name); ++ else ++ cpp_undef (pfile, name); ++} ++ ++/* Helper for TARGET_CPU_CPP_BUILTINS hook. */ ++ ++void ++arc_cpu_cpp_builtins (cpp_reader * pfile) ++{ ++ builtin_assert ("cpu=arc"); ++ builtin_assert ("machine=arc"); ++ ++ builtin_define ("__arc__"); ++ ++#undef ARC_C_DEF ++#define ARC_C_DEF(NAME, CONDITION) \ ++ def_or_undef_macro (pfile, NAME, CONDITION); ++ ++#include "arc-c.def" ++#undef ARC_C_DEF ++ ++ builtin_define_with_int_value ("__ARC_TLS_REGNO__", ++ arc_tp_regno); ++ ++ builtin_define (TARGET_BIG_ENDIAN ++ ? "__BIG_ENDIAN__" : "__LITTLE_ENDIAN__"); ++ if (TARGET_BIG_ENDIAN) ++ builtin_define ("__big_endian__"); ++ ++} +diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def +new file mode 100644 +index 000000000000..065e97360ded +--- /dev/null ++++ b/gcc/config/arc/arc-c.def +@@ -0,0 +1,68 @@ ++/* Copyright (C) 2016 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 ++ . ++*/ ++ ++ARC_C_DEF ("__ARC600__", TARGET_ARC600) ++ARC_C_DEF ("__ARC601__", TARGET_ARC601) ++ARC_C_DEF ("__ARC700__", TARGET_ARC700) ++ARC_C_DEF ("__ARCEM__", TARGET_EM) ++ARC_C_DEF ("__ARCHS__", TARGET_HS) ++ARC_C_DEF ("__ARC_ATOMIC__", TARGET_ATOMIC) ++ARC_C_DEF ("__ARC_NORM__", TARGET_NORM) ++ARC_C_DEF ("__ARC_MUL64__", TARGET_MUL64_SET) ++ARC_C_DEF ("__ARC_MUL32BY16__", TARGET_MULMAC_32BY16_SET) ++ARC_C_DEF ("__ARC_SIMD__", TARGET_SIMD_SET) ++ ++ARC_C_DEF ("__ARC_BARREL_SHIFTER__", TARGET_BARREL_SHIFTER) ++ ++ARC_C_DEF ("__ARC_LL64__", TARGET_LL64) ++ARC_C_DEF ("__ARC_MPY__", TARGET_MPY) ++ARC_C_DEF ("__ARC_SWAP__", TARGET_SWAP) ++ARC_C_DEF ("__ARC_EA__", TARGET_EA_SET) ++ARC_C_DEF ("__ARC_FPX_SP__", (TARGET_SPFP_FAST_SET || TARGET_SPFP_COMPACT_SET)) ++ARC_C_DEF ("__ARC_FPX_DP__", (TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET)) ++ARC_C_DEF ("__ARC_MULT32__", TARGET_MUL64_SET) ++ARC_C_DEF ("__ARC_DIVREM__", TARGET_DIVREM) ++ ++ARC_C_DEF ("__ARC_CODE_DENSITY__", TARGET_CODE_DENSITY) ++ ++ARC_C_DEF ("__ARC_MPY_WLHX__", (arc_mpy_option >= 2)) ++ARC_C_DEF ("__ARC_MPY_WLH1__", (arc_mpy_option == 2)) ++ARC_C_DEF ("__ARC_MPY_WLH2__", (arc_mpy_option == 3)) ++ARC_C_DEF ("__ARC_MPY_WLH3__", (arc_mpy_option == 4)) ++ARC_C_DEF ("__ARC_MPY_WLH4__", (arc_mpy_option == 5)) ++ARC_C_DEF ("__ARC_MPY_WLH5__", (arc_mpy_option == 6)) ++ARC_C_DEF ("__ARC_MPY_DMPY__", (arc_mpy_option == 7)) ++ARC_C_DEF ("__ARC_MPY_MACD__", (arc_mpy_option == 8)) ++ARC_C_DEF ("__ARC_MPY_QMACW__", (arc_mpy_option == 9)) ++ ++ARC_C_DEF ("__ARC_FPU_SP__", TARGET_FP_SP_BASE) ++ARC_C_DEF ("__ARC_FPU_DP__", TARGET_FP_DP_BASE) ++ARC_C_DEF ("__ARC_FPU_SP_DIV__", TARGET_FP_SP_SQRT) ++ARC_C_DEF ("__ARC_FPU_DP_DIV__", TARGET_FP_DP_SQRT) ++ARC_C_DEF ("__ARC_FPU_SP_FMA__", TARGET_FP_SP_FUSED) ++ARC_C_DEF ("__ARC_FPU_DP_FMA__", TARGET_FP_DP_FUSED) ++ARC_C_DEF ("__ARC_FPU_ASSIST__", TARGET_FP_DP_AX) ++ ++/* To be deprecated. */ ++ARC_C_DEF ("__A6__", TARGET_ARC600) ++ARC_C_DEF ("__A7__", TARGET_ARC700) ++ARC_C_DEF ("__EM__", TARGET_EM) ++ARC_C_DEF ("__HS__", TARGET_HS) ++ARC_C_DEF ("__Xnorm", TARGET_NORM) ++ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER) +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 8630e2d84daa..b6ed39268c25 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -123,3 +123,4 @@ extern int arc_return_slot_offset (void); + extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int); + extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool); + extern bool insn_is_tls_gd_dispatch (rtx_insn *); ++extern void arc_cpu_cpp_builtins (cpp_reader *); +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index f6b85ea7e51b..c02e1cd4c777 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -64,61 +64,7 @@ along with GCC; see the file COPYING3. If not see + #undef CC1_SPEC + + /* Names to predefine in the preprocessor for this target machine. */ +-#define TARGET_CPU_CPP_BUILTINS() \ +- do { \ +- builtin_define ("__arc__"); \ +- if (TARGET_ARC600) \ +- { \ +- builtin_define ("__A6__"); \ +- builtin_define ("__ARC600__"); \ +- } \ +- else if (TARGET_ARC601) \ +- { \ +- builtin_define ("__ARC601__"); \ +- } \ +- else if (TARGET_ARC700) \ +- { \ +- builtin_define ("__A7__"); \ +- builtin_define ("__ARC700__"); \ +- } \ +- else if (TARGET_EM) \ +- { \ +- builtin_define ("__EM__"); \ +- } \ +- else if (TARGET_HS) \ +- { \ +- builtin_define ("__HS__"); \ +- } \ +- if (TARGET_ATOMIC) \ +- { \ +- builtin_define ("__ARC_ATOMIC__"); \ +- } \ +- if (TARGET_NORM) \ +- { \ +- builtin_define ("__ARC_NORM__");\ +- builtin_define ("__Xnorm"); \ +- } \ +- if (TARGET_LL64) \ +- { \ +- builtin_define ("__ARC_LL64__");\ +- } \ +- if (TARGET_MUL64_SET) \ +- builtin_define ("__ARC_MUL64__");\ +- if (TARGET_MULMAC_32BY16_SET) \ +- builtin_define ("__ARC_MUL32BY16__");\ +- if (TARGET_SIMD_SET) \ +- builtin_define ("__ARC_SIMD__"); \ +- if (TARGET_BARREL_SHIFTER) \ +- builtin_define ("__Xbarrel_shifter");\ +- builtin_define_with_int_value ("__ARC_TLS_REGNO__", \ +- arc_tp_regno); \ +- builtin_assert ("cpu=arc"); \ +- builtin_assert ("machine=arc"); \ +- builtin_define (TARGET_BIG_ENDIAN \ +- ? "__BIG_ENDIAN__" : "__LITTLE_ENDIAN__"); \ +- if (TARGET_BIG_ENDIAN) \ +- builtin_define ("__big_endian__"); \ +-} while(0) ++#define TARGET_CPU_CPP_BUILTINS() arc_cpu_cpp_builtins (pfile) + + #if DEFAULT_LIBC == LIBC_UCLIBC + +diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc +new file mode 100644 +index 000000000000..4252e73cabb5 +--- /dev/null ++++ b/gcc/config/arc/t-arc +@@ -0,0 +1,29 @@ ++# GCC Makefile fragment for Synopsys DesignWare ARC. ++# ++# Copyright (C) 2016 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 ++# . ++ ++TM_H += $(srcdir)/config/arc/arc-c.def ++ ++arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \ ++$(TREE_H) $(TM_H) $(TM_P_H) coretypes.h ++ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ ++ $(srcdir)/config/arc/arc-c.c ++ ++# Local Variables: ++# mode: Makefile ++# End: +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0021-Use-GOTOFFPC-relocation-for-pc-relative-accesses.patch b/toolchain/gcc/patches/6.3.0/0021-Use-GOTOFFPC-relocation-for-pc-relative-accesses.patch new file mode 100644 index 0000000..7e0e7fe --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0021-Use-GOTOFFPC-relocation-for-pc-relative-accesses.patch @@ -0,0 +1,197 @@ +From bef9f64e64899b7cda46a24e1ace689b88e06429 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 2 May 2016 15:45:14 +0200 +Subject: [PATCH 21/89] Use GOTOFFPC relocation for pc-relative accesses. + +gcc/ +2016-05-02 Claudiu Zissulescu + Joern Rennecke + + * config/arc/arc.c (arc_print_operand_address): Handle pc-relative + addresses. + (arc_needs_pcl_p): Add GOTOFFPC. + (arc_legitimate_pic_addr_p): Likewise. + (arc_output_pic_addr_const): Likewise. + (arc_legitimize_pic_address): Generate a pc-relative address using + GOTOFFPC. + (arc_output_libcall): Use @pcl syntax. + (arc_delegitimize_address_0): Delegitimize ARC_UNSPEC_GOTOFFPC. + * config/arc/arc.md ("unspec"): Add ARC_UNSPEC_GOTOFFPC. + (*movsi_insn): Use @pcl syntax. + (doloop_begin_i): Likewise. + +Signed-off-by: Claudiu Zissulescu +--- + gcc/config/arc/arc.c | 53 ++++++++++++++++++++++++++++----------------------- + gcc/config/arc/arc.md | 6 ++++-- + 2 files changed, 33 insertions(+), 26 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 49edc0a7f657..c0aa075cddb9 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -3528,7 +3528,8 @@ arc_print_operand_address (FILE *file , rtx addr) + || XINT (c, 1) == UNSPEC_TLS_IE)) + || (GET_CODE (c) == PLUS + && GET_CODE (XEXP (c, 0)) == UNSPEC +- && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF))) ++ && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF ++ || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC))) + { + arc_output_pic_addr_const (file, c, 0); + break; +@@ -4636,6 +4637,7 @@ arc_needs_pcl_p (rtx x) + switch (XINT (x, 1)) + { + case ARC_UNSPEC_GOT: ++ case ARC_UNSPEC_GOTOFFPC: + case UNSPEC_TLS_GD: + case UNSPEC_TLS_IE: + return true; +@@ -4698,9 +4700,10 @@ arc_legitimate_pic_addr_p (rtx addr) + || XVECLEN (addr, 0) != 1) + return false; + +- /* Must be one of @GOT, @GOTOFF, @tlsgd, tlsie. */ ++ /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */ + if (XINT (addr, 1) != ARC_UNSPEC_GOT + && XINT (addr, 1) != ARC_UNSPEC_GOTOFF ++ && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC + && XINT (addr, 1) != UNSPEC_TLS_GD + && XINT (addr, 1) != UNSPEC_TLS_IE) + return false; +@@ -4917,26 +4920,15 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + else if (!flag_pic) + return orig; + else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr)) +- { +- /* This symbol may be referenced via a displacement from the +- PIC base address (@GOTOFF). */ ++ return gen_rtx_CONST (Pmode, ++ gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ++ ARC_UNSPEC_GOTOFFPC)); + +- /* FIXME: if we had a way to emit pc-relative adds that +- don't create a GOT entry, we could do without the use of +- the gp register. */ +- crtl->uses_pic_offset_table = 1; +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOTOFF); +- pat = gen_rtx_CONST (Pmode, pat); +- pat = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, pat); +- } +- else +- { +- /* This symbol must be referenced via a load from the +- Global Offset Table (@GOTPC). */ +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT); +- pat = gen_rtx_CONST (Pmode, pat); +- pat = gen_const_mem (Pmode, pat); +- } ++ /* This symbol must be referenced via a load from the Global ++ Offset Table (@GOTPC). */ ++ pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT); ++ pat = gen_rtx_CONST (Pmode, pat); ++ pat = gen_const_mem (Pmode, pat); + + if (oldx == NULL) + oldx = gen_reg_rtx (Pmode); +@@ -4952,6 +4944,7 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + if (GET_CODE (addr) == UNSPEC) + { + /* Check that the unspec is one of the ones we generate? */ ++ return orig; + } + else + gcc_assert (GET_CODE (addr) == PLUS); +@@ -5105,6 +5098,9 @@ arc_output_pic_addr_const (FILE * file, rtx x, int code) + case ARC_UNSPEC_GOTOFF: + suffix = "@gotoff"; + break; ++ case ARC_UNSPEC_GOTOFFPC: ++ suffix = "@pcl", pcrel = true; ++ break; + case ARC_UNSPEC_PLT: + suffix = "@plt"; + break; +@@ -5389,6 +5385,7 @@ arc_legitimate_constant_p (machine_mode mode, rtx x) + { + case ARC_UNSPEC_PLT: + case ARC_UNSPEC_GOTOFF: ++ case ARC_UNSPEC_GOTOFFPC: + case ARC_UNSPEC_GOT: + case UNSPEC_TLS_GD: + case UNSPEC_TLS_IE: +@@ -7648,7 +7645,7 @@ arc_output_libcall (const char *fname) + || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ())) + { + if (flag_pic) +- sprintf (buf, "add r12,pcl,@%s-(.&-4)\n\tjl%%!%%* [r12]", fname); ++ sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname); + else + sprintf (buf, "jl%%! @%s", fname); + } +@@ -8578,13 +8575,21 @@ arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode) + static rtx + arc_delegitimize_address_0 (rtx x) + { +- rtx u, gp; ++ rtx u, gp, p; + + if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC) + { +- if (XINT (u, 1) == ARC_UNSPEC_GOT) ++ if (XINT (u, 1) == ARC_UNSPEC_GOT ++ || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC) + return XVECEXP (u, 0, 0); + } ++ else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS ++ && GET_CODE (u = XEXP (p, 0)) == UNSPEC ++ && (XINT (u, 1) == ARC_UNSPEC_GOT ++ || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)) ++ return gen_rtx_CONST ++ (GET_MODE (x), ++ gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1))); + else if (GET_CODE (x) == PLUS + && ((REG_P (gp = XEXP (x, 0)) + && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM) +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index a4ee08450a8c..1102c53da260 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -102,6 +102,7 @@ + ;; UNSPEC_GOT 4 symbol to be rerenced through the GOT + ;; UNSPEC_GOTOFF 5 Local symbol.To be referenced relative to the + ;; GOTBASE.(Referenced as @GOTOFF) ++;; UNSPEC_GOTOFFPC 6 Local symbol. To be referenced pc-relative. + ;; ---------------------------------------------------------------------------- + + (define_c_enum "unspec" [ +@@ -111,6 +112,7 @@ + ARC_UNSPEC_PLT + ARC_UNSPEC_GOT + ARC_UNSPEC_GOTOFF ++ ARC_UNSPEC_GOTOFFPC + UNSPEC_TLS_GD + UNSPEC_TLS_LD + UNSPEC_TLS_IE +@@ -725,7 +727,7 @@ + * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\"; + mov%? %0,%1 ;10 + add %0,%S1 ;11 +- * return arc_get_unalign () ? \"add %0,pcl,%1-.+2\" : \"add %0,pcl,%1-.\"; ++ add %0,pcl,%1@pcl ;12 + mov%? %0,%S1%& ;13 + mov%? %0,%S1 ;14 + ld%? %0,%1%& ;15 +@@ -5155,7 +5157,7 @@ + /* ??? Can do better for when a scratch register + is known. But that would require extra testing. */ + arc_clear_unalign (); +- return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1-.+2\;sr r0,[3]; LP_END\;pop_s r0"; ++ return ".p2align 2\;push_s r0\;add r0,pcl,24\;sr r0,[2]; LP_START\;add r0,pcl,.L__GCC__LP%1@pcl\;sr r0,[3]; LP_END\;pop_s r0"; + } + output_asm_insn ((size < 2048 + ? "lp .L__GCC__LP%1" : "sr .L__GCC__LP%1,[3]; LP_END"), +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0022-ARC-New-option-handling-refurbish-multilib-support.patch b/toolchain/gcc/patches/6.3.0/0022-ARC-New-option-handling-refurbish-multilib-support.patch new file mode 100644 index 0000000..4596175 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0022-ARC-New-option-handling-refurbish-multilib-support.patch @@ -0,0 +1,2188 @@ +From b5d629696b5a0f5c138b70104cdcf58b21b66942 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 4 May 2016 15:36:09 +0200 +Subject: [PATCH 22/89] [ARC] New option handling, refurbish multilib support. + +gcc/ +2016-05-09 Claudiu Zissulescu + + * config/arc/arc-arch.h: New file. + * config/arc/arc-arches.def: Likewise. + * config/arc/arc-cpus.def: Likewise. + * config/arc/arc-options.def: Likewise. + * config/arc/t-multilib: Likewise. + * config/arc/genmultilib.awk: Likewise. + * config/arc/genoptions.awk: Likewise. + * config/arc/arc-tables.opt: Likewise. + * config/arc/driver-arc.c: Likewise. + * common/config/arc/arc-common.c (arc_handle_option): Trace + toggled options. + * config.gcc (arc*-*-*): Add arc-tables.opt to arc's extra + options; check for supported cpu against arc-cpus.def file. + (arc*-*-elf*, arc*-*-linux-uclibc*): Use new make fragment; define + TARGET_CPU_BUILD macro; add driver-arc.o as an extra object. + * config/arc/arc-c.def: Add emacs local variables. + * config/arc/arc-opts.h (processor_type): Use arc-cpus.def file. + (FPU_FPUS, FPU_FPUD, FPU_FPUDA, FPU_FPUDA_DIV, FPU_FPUDA_FMA) + (FPU_FPUDA_ALL, FPU_FPUS_DIV, FPU_FPUS_FMA, FPU_FPUS_ALL) + (FPU_FPUD_DIV, FPU_FPUD_FMA, FPU_FPUD_ALL): New defines. + (DEFAULT_arc_fpu_build): Define. + (DEFAULT_arc_mpy_option): Define. + * config/arc/arc-protos.h (arc_init): Delete. + * config/arc/arc.c (arc_cpu_name): New variable. + (arc_selected_cpu, arc_selected_arch, arc_arcem, arc_archs) + (arc_arc700, arc_arc600, arc_arc601): New variable. + (arc_init): Add static; remove selection of default tune value, + cleanup obsolete error messages. + (arc_override_options): Make use of .def files for selecting the + right cpu and option configurations. + * config/arc/arc.h (stdbool.h): Include. + (TARGET_CPU_DEFAULT): Define. + (CPP_SPEC): Remove mcpu=NPS400 handling. + (arc_cpu_to_as): Declare. + (EXTRA_SPEC_FUNCTIONS): Define. + (OPTION_DEFAULT_SPECS): Likewise. + (ASM_DEFAULT): Remove. + (ASM_SPEC): Use arc_cpu_to_as. + (DRIVER_SELF_SPECS): Remove deprecated options. + (arc_arc700, arc_arc600, arc_arc601, arc_arcem, arc_archs): + Declare. + (TARGET_ARC600, TARGET_ARC601, TARGET_ARC700, TARGET_EM) + (TARGET_HS, TARGET_V2, TARGET_ARC600): Make them use arc_arc* + variables. + (MULTILIB_DEFAULTS): Use ARC_MULTILIB_CPU_DEFAULT. + * config/arc/arc.md (attr_cpu): Remove. + * config/arc/arc.opt (arc_mpy_option): Make it target variable. + (mno-mpy): Deprecate. + (mcpu=ARC600, mcpu=ARC601, mcpu=ARC700, mcpu=NPS400, mcpu=ARCEM) + (mcpu=ARCHS): Remove. + (mcrc, mdsp-packa, mdvbf, mmac-d16, mmac-24, mtelephony, mrtsc): + Deprecate. + (mbarrel_shifte, mspfp_, mdpfp_, mdsp_pack, mmac_): Remove. + (arc_fpu): Use new defines. + (arc_seen_options): New target variable. + * config/arc/t-arc (driver-arc.o): New target. + (arc-cpus, t-multilib, arc-tables.opt): Likewise. + * config/arc/t-arc-newlib: Delete. + * config/arc/t-arc-uClibc: Renamed to t-uClibc. + * doc/invoke.texi (ARC): Update arc options. +--- + gcc/common/config/arc/arc-common.c | 162 ++++++++++++++++-------- + gcc/config.gcc | 47 +++---- + gcc/config/arc/arc-arch.h | 120 ++++++++++++++++++ + gcc/config/arc/arc-arches.def | 35 +++++ + gcc/config/arc/arc-c.def | 4 + + gcc/config/arc/arc-cpus.def | 47 +++++++ + gcc/config/arc/arc-options.def | 69 ++++++++++ + gcc/config/arc/arc-opts.h | 47 ++++++- + gcc/config/arc/arc-protos.h | 1 - + gcc/config/arc/arc-tables.opt | 90 +++++++++++++ + gcc/config/arc/arc.c | 186 +++++++++++++++------------ + gcc/config/arc/arc.h | 91 ++++++------- + gcc/config/arc/arc.md | 5 - + gcc/config/arc/arc.opt | 109 +++++----------- + gcc/config/arc/driver-arc.c | 80 ++++++++++++ + gcc/config/arc/genmultilib.awk | 204 ++++++++++++++++++++++++++++++ + gcc/config/arc/genoptions.awk | 85 +++++++++++++ + gcc/config/arc/t-arc | 19 +++ + gcc/config/arc/t-arc-newlib | 46 ------- + gcc/config/arc/t-multilib | 51 ++++++++ + gcc/config/arc/{t-arc-uClibc => t-uClibc} | 0 + gcc/doc/invoke.texi | 86 +++++++++++-- + 22 files changed, 1228 insertions(+), 356 deletions(-) + create mode 100644 gcc/config/arc/arc-arch.h + create mode 100644 gcc/config/arc/arc-arches.def + create mode 100644 gcc/config/arc/arc-cpus.def + create mode 100644 gcc/config/arc/arc-options.def + create mode 100644 gcc/config/arc/arc-tables.opt + create mode 100644 gcc/config/arc/driver-arc.c + create mode 100644 gcc/config/arc/genmultilib.awk + create mode 100644 gcc/config/arc/genoptions.awk + delete mode 100644 gcc/config/arc/t-arc-newlib + create mode 100644 gcc/config/arc/t-multilib + rename gcc/config/arc/{t-arc-uClibc => t-uClibc} (100%) + +diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c +index f5b9c6d3cc98..0141e3d6a23c 100644 +--- a/gcc/common/config/arc/arc-common.c ++++ b/gcc/common/config/arc/arc-common.c +@@ -2,6 +2,7 @@ + Copyright (C) 1994-2016 Free Software Foundation, Inc. + Contributor: Joern Rennecke + on behalf of Synopsys Inc. ++ Claudiu Zissulescu + + This file is part of GCC. + +@@ -62,17 +63,19 @@ static const struct default_options arc_option_optimization_table[] = + + /* Process options. */ + static bool +-arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, ++arc_handle_option (struct gcc_options *opts, ++ struct gcc_options *opts_set ATTRIBUTE_UNUSED, + const struct cl_decoded_option *decoded, + location_t loc) + { + size_t code = decoded->opt_index; + int value = decoded->value; + const char *arg = decoded->arg; ++ static int mcpu_seen = PROCESSOR_NONE; ++ char *p; + + switch (code) + { +- static int mcpu_seen = PROCESSOR_NONE; + case OPT_mcpu_: + /* N.B., at this point arc_cpu has already been set to its new value by + our caller, so comparing arc_cpu with PROCESSOR_NONE is pointless. */ +@@ -80,71 +83,130 @@ arc_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, + if (mcpu_seen != PROCESSOR_NONE && mcpu_seen != value) + warning_at (loc, 0, "multiple -mcpu= options specified."); + mcpu_seen = value; ++ break; ++ ++ case OPT_mmpy_option_: ++ p = ASTRDUP (arg); + +- switch (value) ++ if (!strcmp (p, "0") ++ || !strcmp (p, "none")) ++ opts->x_arc_mpy_option = 0; ++ else if (!strcmp (p, "1") ++ || !strcmp (p, "w")) + { +- case PROCESSOR_NPS400: +- if (! (opts_set->x_TARGET_CASE_VECTOR_PC_RELATIVE) ) +- opts->x_TARGET_CASE_VECTOR_PC_RELATIVE = 1; +- /* Fall through */ +- case PROCESSOR_ARC600: +- case PROCESSOR_ARC700: +- if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) ) +- opts->x_target_flags |= MASK_BARREL_SHIFTER; +- break; +- case PROCESSOR_ARC601: +- if (! (opts_set->x_target_flags & MASK_BARREL_SHIFTER) ) +- opts->x_target_flags &= ~MASK_BARREL_SHIFTER; +- break; +- case PROCESSOR_ARCHS: +- if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER)) +- opts->x_target_flags |= MASK_BARREL_SHIFTER; /* Default: on. */ +- if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY)) +- opts->x_target_flags |= MASK_CODE_DENSITY; /* Default: on. */ +- if ( !(opts_set->x_target_flags & MASK_NORM_SET)) +- opts->x_target_flags |= MASK_NORM_SET; /* Default: on. */ +- if ( !(opts_set->x_target_flags & MASK_SWAP_SET)) +- opts->x_target_flags |= MASK_SWAP_SET; /* Default: on. */ +- if ( !(opts_set->x_target_flags & MASK_DIVREM)) +- opts->x_target_flags |= MASK_DIVREM; /* Default: on. */ +- break; +- +- case PROCESSOR_ARCEM: +- if ( !(opts_set->x_target_flags & MASK_BARREL_SHIFTER)) +- opts->x_target_flags |= MASK_BARREL_SHIFTER; /* Default: on. */ +- if ( !(opts_set->x_target_flags & MASK_CODE_DENSITY)) +- opts->x_target_flags &= ~MASK_CODE_DENSITY; /* Default: off. */ +- if ( !(opts_set->x_target_flags & MASK_NORM_SET)) +- opts->x_target_flags &= ~MASK_NORM_SET; /* Default: off. */ +- if ( !(opts_set->x_target_flags & MASK_SWAP_SET)) +- opts->x_target_flags &= ~MASK_SWAP_SET; /* Default: off. */ +- if ( !(opts_set->x_target_flags & MASK_DIVREM)) +- opts->x_target_flags &= ~MASK_DIVREM; /* Default: off. */ +- break; +- default: +- gcc_unreachable (); ++ opts->x_arc_mpy_option = 1; ++ warning_at (loc, 0, "Unsupported value for mmpy-option"); + } ++ else if (!strcmp (p, "2") ++ || !strcmp (p, "mpy") ++ || !strcmp (p, "wlh1")) ++ opts->x_arc_mpy_option = 2; ++ else if (!strcmp (p, "3") ++ || !strcmp (p, "wlh2")) ++ opts->x_arc_mpy_option = 3; ++ else if (!strcmp (p, "4") ++ || !strcmp (p, "wlh3")) ++ opts->x_arc_mpy_option = 4; ++ else if (!strcmp (p, "5") ++ || !strcmp (p, "wlh4")) ++ opts->x_arc_mpy_option = 5; ++ else if (!strcmp (p, "6") ++ || !strcmp (p, "wlh5")) ++ opts->x_arc_mpy_option = 6; ++ else if (!strcmp (p, "7") ++ || !strcmp (p, "plus_dmpy")) ++ opts->x_arc_mpy_option = 7; ++ else if (!strcmp (p, "8") ++ || !strcmp (p, "plus_macd")) ++ opts->x_arc_mpy_option = 8; ++ else if (!strcmp (p, "9") ++ || !strcmp (p, "plus_qmacw")) ++ opts->x_arc_mpy_option = 9; ++ else ++ error_at (loc, "unknown value %qs for -mmpy-option", arg); ++ + break; + +- case OPT_mmpy_option_: +- if (value < 0 || value > 9) +- error_at (loc, "bad value %qs for -mmpy-option switch", arg); ++ case OPT_mcode_density: ++ opts->x_arc_seen_options |= MASK_CODE_DENSITY; ++ break; ++ ++ case OPT_mdiv_rem: ++ opts->x_arc_seen_options |= MASK_DIVREM; ++ break; ++ ++ case OPT_mnorm: ++ opts->x_arc_seen_options |= MASK_NORM_SET; ++ break; ++ ++ case OPT_matomic: ++ opts->x_arc_seen_options |= MASK_ATOMIC; ++ break; ++ ++ case OPT_mll64: ++ opts->x_arc_seen_options |= MASK_LL64; ++ break; ++ ++ case OPT_mbarrel_shifter: ++ opts->x_arc_seen_options |= MASK_BARREL_SHIFTER; ++ break; ++ ++ case OPT_mswap: ++ opts->x_arc_seen_options |= MASK_SWAP_SET; ++ break; ++ ++ case OPT_mmul64: ++ opts->x_arc_seen_options |= MASK_MUL64_SET; ++ break; ++ ++ case OPT_mmul32x16: ++ opts->x_arc_seen_options |= MASK_MULMAC_32BY16_SET; ++ break; ++ ++ case OPT_mEA: ++ opts->x_arc_seen_options |= MASK_EA_SET; ++ break; ++ ++ case OPT_mspfp: ++ case OPT_mspfp_compact: ++ case OPT_mspfp_fast: ++ opts->x_arc_seen_options |= MASK_SPFP_COMPACT_SET; ++ break; ++ ++ case OPT_mdpfp: ++ case OPT_mdpfp_compact: ++ case OPT_mdpfp_fast: ++ opts->x_arc_seen_options |= MASK_DPFP_COMPACT_SET; ++ break; ++ ++ case OPT_margonaut: ++ opts->x_arc_seen_options |= MASK_ARGONAUT_SET; ++ break; ++ ++ case OPT_msimd: ++ opts->x_arc_seen_options |= MASK_SIMD_SET; ++ break; ++ ++ default: + break; + } + + return true; + } + ++#undef TARGET_OPTION_INIT_STRUCT + #define TARGET_OPTION_INIT_STRUCT arc_option_init_struct ++ ++#undef TARGET_OPTION_OPTIMIZATION_TABLE + #define TARGET_OPTION_OPTIMIZATION_TABLE arc_option_optimization_table +-#define TARGET_HANDLE_OPTION arc_handle_option + + #define DEFAULT_NO_SDATA (TARGET_SDATA_DEFAULT ? 0 : MASK_NO_SDATA_SET) + +-/* We default to ARC700, which has the barrel shifter enabled. */ +-#define TARGET_DEFAULT_TARGET_FLAGS \ +- (MASK_BARREL_SHIFTER|MASK_VOLATILE_CACHE_SET|DEFAULT_NO_SDATA) ++#undef TARGET_DEFAULT_TARGET_FLAGS ++#define TARGET_DEFAULT_TARGET_FLAGS (DEFAULT_NO_SDATA | MASK_VOLATILE_CACHE_SET) + ++#undef TARGET_HANDLE_OPTION ++#define TARGET_HANDLE_OPTION arc_handle_option + + #include "common/common-target-def.h" + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 2cc649e1dc83..fbf77d3e6347 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -325,6 +325,7 @@ arc*-*-*) + cpu_type=arc + c_target_objs="arc-c.o" + cxx_target_objs="arc-c.o" ++ extra_options="${extra_options} arc/arc-tables.opt" + ;; + arm*-*-*) + cpu_type=arm +@@ -1002,13 +1003,12 @@ alpha*-dec-*vms*) + ;; + arc*-*-elf*) + extra_headers="arc-simd.h" +- tm_file="dbxelf.h elfos.h newlib-stdint.h ${tm_file}" +- tmake_file="arc/t-arc-newlib arc/t-arc" +- case x"${with_cpu}" in +- xarc600|xarc601|xarc700) +- target_cpu_default="TARGET_CPU_$with_cpu" +- ;; +- esac ++ tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}" ++ tmake_file="arc/t-multilib arc/t-arc" ++ extra_gcc_objs="driver-arc.o" ++ if test "x$with_cpu" != x; then ++ tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu" ++ fi + if test x${with_endian} = x; then + case ${target} in + arc*be-*-* | arc*eb-*-*) with_endian=big ;; +@@ -1025,15 +1025,14 @@ arc*-*-elf*) + ;; + arc*-*-linux-uclibc*) + extra_headers="arc-simd.h" +- tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}" +- tmake_file="${tmake_file} arc/t-arc-uClibc arc/t-arc" ++ tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}" ++ tmake_file="${tmake_file} arc/t-uClibc arc/t-arc" + tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0" + tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1" +- case x"${with_cpu}" in +- xarc600|xarc601|xarc700) +- target_cpu_default="TARGET_CPU_$with_cpu" +- ;; +- esac ++ extra_gcc_objs="driver-arc.o" ++ if test "x$with_cpu" != x; then ++ tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu" ++ fi + if test x${with_endian} = x; then + case ${target} in + arc*be-*-* | arc*eb-*-*) with_endian=big ;; +@@ -3693,15 +3692,19 @@ case "${target}" in + done + ;; + +- arc*-*-*) # was: arc*-*-linux-uclibc) ++ arc*-*-*) + supported_defaults="cpu" +- case $with_cpu in +- arc600|arc601|arc700) +- ;; +- *) echo "Unknown cpu type" +- exit 1 +- ;; +- esac ++ ++ if [ x"$with_cpu" = x ] \ ++ || grep "^ARC_CPU ($with_cpu," \ ++ ${srcdir}/config/arc/arc-cpus.def \ ++ > /dev/null; then ++ # Ok ++ true ++ else ++ echo "Unknown cpu used in --with-cpu=$with_cpu" 1>&2 ++ exit 1 ++ fi + ;; + + arm*-*-*) +diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h +new file mode 100644 +index 000000000000..c789296c9cc0 +--- /dev/null ++++ b/gcc/config/arc/arc-arch.h +@@ -0,0 +1,120 @@ ++/* Definitions of types that are used to store ARC architecture and ++ device information. ++ Copyright (C) 2016 Free Software Foundation, Inc. ++ Contributed by Claudiu Zissulescu (claziss@synopsys.com) ++ ++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 ++. */ ++ ++#ifndef GCC_ARC_ARCH_H ++#define GCC_ARC_ARCH_H ++ ++#ifndef IN_LIBGCC2 ++/* Architecture selection types. */ ++ ++enum cpu_flags ++ { ++#define ARC_OPT(NAME, CODE, MASK, DOC) NAME = CODE, ++#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) NAME = CODE, ++#include "arc-options.def" ++#undef ARC_OPT ++#undef ARC_OPTX ++ FL_END ++ }; ++ ++ ++/* ARC architecture variants. */ ++ ++enum base_architecture ++ { ++ BASE_ARCH_NONE, ++#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS) BASE_ARCH_##ARCH, ++#include "arc-arches.def" ++#undef ARC_ARCH ++ BASE_ARCH_END ++ }; ++ ++ ++/* Tune variants. Needs to match the attr_tune enum. */ ++ ++enum arc_tune_attr ++ { ++ ARC_TUNE_NONE, ++ ARC_TUNE_ARC600, ++ ARC_TUNE_ARC700_4_2_STD, ++ ARC_TUNE_ARC700_4_2_XMAC ++ }; ++ ++/* CPU specific properties. */ ++ ++typedef struct ++{ ++ /* CPU name. */ ++ const char *const name; ++ ++ /* Architecture class. */ ++ enum base_architecture arch; ++ ++ /* Specific flags. */ ++ const unsigned long long flags; ++ ++ /* Tune value. */ ++ enum arc_tune_attr tune; ++} arc_cpu_t; ++ ++ ++/* Architecture specific propoerties. */ ++ ++typedef struct ++{ ++ /* Architecture name. */ ++ const char *const name; ++ ++ /* Architecture class. */ ++ enum base_architecture arch; ++ ++ /* All allowed flags for this architecture. */ ++ const unsigned long long flags; ++ ++ /* Default flags for this architecture. It is a subset of ++ FLAGS. */ ++ const unsigned long long dflags; ++} arc_arch_t; ++ ++ ++ ++const arc_arch_t arc_arch_types[] = ++ { ++ {"none", BASE_ARCH_NONE, 0, 0}, ++#define ARC_ARCH(NAME, ARCH, FLAGS, DFLAGS) \ ++ {NAME, BASE_ARCH_##ARCH, FLAGS, DFLAGS}, ++#include "arc-arches.def" ++#undef ARC_ARCH ++ {NULL, BASE_ARCH_END, 0, 0} ++ }; ++ ++const arc_cpu_t arc_cpu_types[] = ++ { ++ {"none", BASE_ARCH_NONE, 0, ARC_TUNE_NONE}, ++#define ARC_CPU(NAME, ARCH, FLAGS, TUNE) \ ++ {#NAME, BASE_ARCH_##ARCH, FLAGS, ARC_TUNE_##TUNE}, ++#include "arc-cpus.def" ++#undef ARC_CPU ++ {NULL, BASE_ARCH_END, 0, ARC_TUNE_NONE} ++ }; ++ ++#endif ++#endif /* GCC_ARC_ARCH_H */ +diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def +new file mode 100644 +index 000000000000..da69a1a8230c +--- /dev/null ++++ b/gcc/config/arc/arc-arches.def +@@ -0,0 +1,35 @@ ++/* ARC ARCH architectures. ++ Copyright (C) 2016 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 ++ . */ ++ ++ARC_ARCH("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM \ ++ | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP \ ++ | FL_SIMD | FL_FPUDA, 0) ++ARC_ARCH("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD \ ++ | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP \ ++ | FL_FPUS | FL_FPUD, \ ++ FL_CD | FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP) ++ARC_ARCH("arc6xx", 6xx, FL_BS | FL_NORM | FL_SWAP | FL_MUL64 | FL_MUL32x16 \ ++ | FL_SPFP | FL_ARGONAUT | FL_DPFP, 0) ++ARC_ARCH("arc700", 700, FL_ATOMIC | FL_BS | FL_NORM | FL_SWAP | FL_EA \ ++ | FL_SIMD | FL_SPFP | FL_ARGONAUT | FL_DPFP, \ ++ FL_BS | FL_NORM | FL_SWAP) ++ ++/* Local Variables: */ ++/* mode: c */ ++/* End: */ +diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def +index 065e97360ded..4cfd7b6e35fd 100644 +--- a/gcc/config/arc/arc-c.def ++++ b/gcc/config/arc/arc-c.def +@@ -66,3 +66,7 @@ ARC_C_DEF ("__EM__", TARGET_EM) + ARC_C_DEF ("__HS__", TARGET_HS) + ARC_C_DEF ("__Xnorm", TARGET_NORM) + ARC_C_DEF ("__Xbarrel_shifter", TARGET_BARREL_SHIFTER) ++ ++/* Local Variables: */ ++/* mode: c */ ++/* End: */ +diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def +new file mode 100644 +index 000000000000..6d93c89e04a4 +--- /dev/null ++++ b/gcc/config/arc/arc-cpus.def +@@ -0,0 +1,47 @@ ++/* ARC CPU architectures. ++ Copyright (C) 2016 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 ++ . */ ++ ++ARC_CPU (em, em, 0, NONE) ++ARC_CPU (arcem, em, FL_MPYOPT_2|FL_CD|FL_BS, NONE) ++ARC_CPU (em4, em, FL_CD, NONE) ++ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE) ++ARC_CPU (em4_fpus, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE) ++ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE) ++ ++ARC_CPU (hs, hs, 0, NONE) ++ARC_CPU (archs, hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE) ++ARC_CPU (hs34, hs, FL_MPYOPT_2, NONE) ++ARC_CPU (hs38, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64, NONE) ++ARC_CPU (hs38_linux, hs, FL_MPYOPT_9|FL_DIVREM|FL_LL64|FL_FPU_FPUD_ALL, NONE) ++ ++ARC_CPU (arc600, 6xx, FL_BS, ARC600) ++ARC_CPU (arc600_norm, 6xx, FL_BS|FL_NORM, ARC600) ++ARC_CPU (arc600_mul64, 6xx, FL_BS|FL_NORM|FL_MUL64, ARC600) ++ARC_CPU (arc600_mul32x16, 6xx, FL_BS|FL_NORM|FL_MUL32x16, ARC600) ++ARC_CPU (arc601, 6xx, 0, ARC600) ++ARC_CPU (arc601_norm, 6xx, FL_NORM, ARC600) ++ARC_CPU (arc601_mul64, 6xx, FL_NORM|FL_MUL64, ARC600) ++ARC_CPU (arc601_mul32x16, 6xx, FL_NORM|FL_MUL32x16, ARC600) ++ ++ARC_CPU (arc700, 700, 0, ARC700_4_2_STD) ++ARC_CPU (nps400, 700, 0, ARC700_4_2_STD) ++ ++/* Local Variables: */ ++/* mode: c */ ++/* End: */ +diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def +new file mode 100644 +index 000000000000..3834894a0884 +--- /dev/null ++++ b/gcc/config/arc/arc-options.def +@@ -0,0 +1,69 @@ ++/* ARC options. ++ Copyright (C) 2016 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 ++ . */ ++ ++ARC_OPT (FL_CD, (1ULL << 0), MASK_CODE_DENSITY, "code density") ++ARC_OPT (FL_DIVREM, (1ULL << 1), MASK_DIVREM, "div/rem") ++ARC_OPT (FL_NORM, (1ULL << 2), MASK_NORM_SET, "norm") ++ ++ARC_OPT (FL_ATOMIC, (1ULL << 4), MASK_ATOMIC, "atomic") ++ARC_OPT (FL_LL64, (1ULL << 5), MASK_LL64, "double load/store") ++ARC_OPT (FL_BS, (1ULL << 6), MASK_BARREL_SHIFTER, "barrel shifter") ++ARC_OPT (FL_SWAP, (1ULL << 7), MASK_SWAP_SET, "swap") ++ARC_OPT (FL_MUL64, (1ULL << 8), MASK_MUL64_SET, "mul64") ++ARC_OPT (FL_MUL32x16, (1ULL << 9), MASK_MULMAC_32BY16_SET, "mul32x16") ++ ++ARC_OPT (FL_EA, (1ULL << 11), MASK_EA_SET, "extended arithmetics") ++ARC_OPT (FL_SPFP, (1ULL << 12), MASK_SPFP_COMPACT_SET, "single precission FPX") ++ARC_OPT (FL_DPFP, (1ULL << 13), MASK_DPFP_COMPACT_SET, "double precission FPX") ++ARC_OPT (FL_ARGONAUT, (1ULL << 14), MASK_ARGONAUT_SET, "argonaut") ++ARC_OPT (FL_SIMD, (1ULL << 15), MASK_SIMD_SET, "simd") ++ ++ARC_OPTX (FL_MPYOPT_1, (1ULL << 17), arc_mpy_option, 1, "mpy option w") ++ARC_OPTX (FL_MPYOPT_2, (1ULL << 18), arc_mpy_option, 2, "mpy option wlh1") ++ARC_OPTX (FL_MPYOPT_3, (1ULL << 19), arc_mpy_option, 3, "mpy option wlh2") ++ARC_OPTX (FL_MPYOPT_4, (1ULL << 20), arc_mpy_option, 4, "mpy option wlh3") ++ARC_OPTX (FL_MPYOPT_5, (1ULL << 21), arc_mpy_option, 5, "mpy option wlh4") ++ARC_OPTX (FL_MPYOPT_6, (1ULL << 22), arc_mpy_option, 6, "mpy option wlh5") ++ARC_OPTX (FL_MPYOPT_7, (1ULL << 23), arc_mpy_option, 7, "mpy option plus_dmpy") ++ARC_OPTX (FL_MPYOPT_8, (1ULL << 24), arc_mpy_option, 8, "mpy option plus_macd") ++ARC_OPTX (FL_MPYOPT_9, (1ULL << 25), arc_mpy_option, 9, "mpy option plus_qmacw") ++ ++ARC_OPT (FL_MPYOPT_7_9, (0x01c2ULL << 17), 0, "mpy option") ++ARC_OPT (FL_MPYOPT_1_6, (0x003fULL << 17), 0, "mpy option") ++ ++ARC_OPTX (FL_FPU_FPUS, (1ULL << 26), arc_fpu_build, FPU_FPUS, "mfpu=fpus") ++ARC_OPTX (FL_FPU_FPUS_DIV, (1ULL << 27), arc_fpu_build, FPU_FPUS_DIV, "mfpu=fpus_div") ++ARC_OPTX (FL_FPU_FPUS_FMA, (1ULL << 28), arc_fpu_build, FPU_FPUS_FMA, "mfpu=fpus_fma") ++ARC_OPTX (FL_FPU_FPUS_ALL, (1ULL << 29), arc_fpu_build, FPU_FPUS_ALL, "mfpu=fpus_all") ++ARC_OPTX (FL_FPU_FPUDA, (1ULL << 30), arc_fpu_build, FPU_FPUDA, "mfpu=fpuda") ++ARC_OPTX (FL_FPU_FPUDA_DIV, (1ULL << 31), arc_fpu_build, FPU_FPUDA_DIV, "mfpu=fpuda_div") ++ARC_OPTX (FL_FPU_FPUDA_FMA, (1ULL << 32), arc_fpu_build, FPU_FPUDA_FMA, "mfpu=fpuda_fma") ++ARC_OPTX (FL_FPU_FPUDA_ALL, (1ULL << 33), arc_fpu_build, FPU_FPUDA_ALL, "mfpu=fpuda_all") ++ARC_OPTX (FL_FPU_FPUD, (1ULL << 34), arc_fpu_build, FPU_FPUD, "mfpu=fpud") ++ARC_OPTX (FL_FPU_FPUD_DIV, (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV, "mfpu=fpud_div") ++ARC_OPTX (FL_FPU_FPUD_FMA, (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA, "mfpu=fpud_fma") ++ARC_OPTX (FL_FPU_FPUD_ALL, (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL, "mfpu=fpud_all") ++ ++ARC_OPT (FL_FPUS, (0xFULL << 26), 0, "single precission floating point") ++ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist") ++ARC_OPT (FL_FPUD, (0xF0FULL << 26), 0, "double precission floating point") ++ ++/* Local Variables: */ ++/* mode: c */ ++/* End: */ +diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h +index cbd78985dd8b..81446b4a412a 100644 +--- a/gcc/config/arc/arc-opts.h ++++ b/gcc/config/arc/arc-opts.h +@@ -18,15 +18,16 @@ + along with GCC; see the file COPYING3. If not see + . */ + ++#ifndef ARC_OPTS_H ++#define ARC_OPTS_H ++ + enum processor_type + { +- PROCESSOR_NONE, +- PROCESSOR_ARC600, +- PROCESSOR_ARC601, +- PROCESSOR_ARC700, +- PROCESSOR_NPS400, +- PROCESSOR_ARCEM, +- PROCESSOR_ARCHS ++ PROCESSOR_NONE = 0, ++#define ARC_CPU(NAME, ARCH, FLAGS, TUNE) PROCESSOR_##NAME, ++#include "arc-cpus.def" ++#undef ARC_CPU ++ PROCESSOR_generic + }; + + /* Single precision floating point. */ +@@ -48,3 +49,35 @@ enum processor_type + /* Double precision floating point assist operations. */ + #define FPX_DP 0x0100 + ++/* fpus option combi. */ ++#define FPU_FPUS (FPU_SP | FPU_SC) ++/* fpud option combi. */ ++#define FPU_FPUD (FPU_SP | FPU_SC | FPU_DP | FPU_DC) ++/* fpuda option combi. */ ++#define FPU_FPUDA (FPU_SP | FPU_SC | FPX_DP) ++/* fpuda_div option combi. */ ++#define FPU_FPUDA_DIV (FPU_SP | FPU_SC | FPU_SD | FPX_DP) ++/* fpuda_fma option combi. */ ++#define FPU_FPUDA_FMA (FPU_SP | FPU_SC | FPU_SF | FPX_DP) ++/* fpuda_all option combi. */ ++#define FPU_FPUDA_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD | FPX_DP) ++/* fpus_div option combi. */ ++#define FPU_FPUS_DIV (FPU_SP | FPU_SC | FPU_SD) ++/* fpus_fma option combi. */ ++#define FPU_FPUS_FMA (FPU_SP | FPU_SC | FPU_SF) ++/* fpus_all option combi. */ ++#define FPU_FPUS_ALL (FPU_SP | FPU_SC | FPU_SF | FPU_SD) ++/* fpud_div option combi. */ ++#define FPU_FPUD_DIV (FPU_FPUS_DIV | FPU_DP | FPU_DC | FPU_DD) ++/* fpud_fma option combi. */ ++#define FPU_FPUD_FMA (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF) ++/* fpud_all option combi. */ ++#define FPU_FPUD_ALL (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD) ++ ++/* Default FPU option value. */ ++#define DEFAULT_arc_fpu_build 0x10000000 ++ ++/* Default MPY option value. */ ++#define DEFAULT_arc_mpy_option -1 ++ ++#endif /* ARC_OPTS_H */ +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index b6ed39268c25..0e9476699ee3 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -52,7 +52,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *); + #endif /* TREE_CODE */ + + +-extern void arc_init (void); + extern unsigned int arc_compute_frame_size (int); + extern bool arc_ccfsm_branch_deleted_p (void); + extern void arc_ccfsm_record_branch_deleted (void); +diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt +new file mode 100644 +index 000000000000..0e7c50c7be78 +--- /dev/null ++++ b/gcc/config/arc/arc-tables.opt +@@ -0,0 +1,90 @@ ++; Auto-generated Makefile Snip ++; Generated by : ./gcc/config/arc/genoptions.awk ++; Generated from : ./gcc/config/arc/arc-cpu.def ++; ++; Copyright (C) 2016 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 ++; . ++ ++Enum ++Name(processor_type) Type(enum processor_type) ++Known ARC CPUs (for use with the -mcpu= option): ++ ++EnumValue ++Enum(processor_type) String(em) Value(PROCESSOR_em) ++ ++EnumValue ++Enum(processor_type) String(arcem) Value(PROCESSOR_arcem) ++ ++EnumValue ++Enum(processor_type) String(em4) Value(PROCESSOR_em4) ++ ++EnumValue ++Enum(processor_type) String(em4_dmips) Value(PROCESSOR_em4_dmips) ++ ++EnumValue ++Enum(processor_type) String(em4_fpus) Value(PROCESSOR_em4_fpus) ++ ++EnumValue ++Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda) ++ ++EnumValue ++Enum(processor_type) String(hs) Value(PROCESSOR_hs) ++ ++EnumValue ++Enum(processor_type) String(archs) Value(PROCESSOR_archs) ++ ++EnumValue ++Enum(processor_type) String(hs34) Value(PROCESSOR_hs34) ++ ++EnumValue ++Enum(processor_type) String(hs38) Value(PROCESSOR_hs38) ++ ++EnumValue ++Enum(processor_type) String(hs38_linux) Value(PROCESSOR_hs38_linux) ++ ++EnumValue ++Enum(processor_type) String(arc600) Value(PROCESSOR_arc600) ++ ++EnumValue ++Enum(processor_type) String(arc600_norm) Value(PROCESSOR_arc600_norm) ++ ++EnumValue ++Enum(processor_type) String(arc600_mul64) Value(PROCESSOR_arc600_mul64) ++ ++EnumValue ++Enum(processor_type) String(arc600_mul32x16) Value(PROCESSOR_arc600_mul32x16) ++ ++EnumValue ++Enum(processor_type) String(arc601) Value(PROCESSOR_arc601) ++ ++EnumValue ++Enum(processor_type) String(arc601_norm) Value(PROCESSOR_arc601_norm) ++ ++EnumValue ++Enum(processor_type) String(arc601_mul64) Value(PROCESSOR_arc601_mul64) ++ ++EnumValue ++Enum(processor_type) String(arc601_mul32x16) Value(PROCESSOR_arc601_mul32x16) ++ ++EnumValue ++Enum(processor_type) String(arc700) Value(PROCESSOR_arc700) ++ ++EnumValue ++Enum(processor_type) String(nps400) Value(PROCESSOR_nps400) ++ ++ +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index c0aa075cddb9..985df8151d74 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -64,7 +64,8 @@ along with GCC; see the file COPYING3. If not see + #include "alias.h" + + /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */ +-static const char *arc_cpu_string = ""; ++static char arc_cpu_name[10] = ""; ++static const char *arc_cpu_string = arc_cpu_name; + + /* ??? Loads can handle any constant, stores can only handle small ones. */ + /* OTOH, LIMMs cost extra, so their usefulness is limited. */ +@@ -241,6 +242,16 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT, + enum by_pieces_operation op, + bool); + ++static const arc_cpu_t *arc_selected_cpu; ++static const arc_arch_t *arc_selected_arch; ++ ++/* Global var which sets the current compilation architecture. */ ++bool arc_arcem = false; ++bool arc_archs = false; ++bool arc_arc700 = false; ++bool arc_arc600 = false; ++bool arc_arc601 = false; ++ + /* Implements target hook vector_mode_supported_p. */ + + static bool +@@ -668,47 +679,9 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt) + + /* Called by OVERRIDE_OPTIONS to initialize various things. */ + +-void ++static void + arc_init (void) + { +- enum attr_tune tune_dflt = TUNE_NONE; +- +- switch (arc_cpu) +- { +- case PROCESSOR_ARC600: +- arc_cpu_string = "ARC600"; +- tune_dflt = TUNE_ARC600; +- break; +- +- case PROCESSOR_ARC601: +- arc_cpu_string = "ARC601"; +- tune_dflt = TUNE_ARC600; +- break; +- +- case PROCESSOR_ARC700: +- arc_cpu_string = "ARC700"; +- tune_dflt = TUNE_ARC700_4_2_STD; +- break; +- +- case PROCESSOR_NPS400: +- arc_cpu_string = "NPS400"; +- tune_dflt = TUNE_ARC700_4_2_STD; +- break; +- +- case PROCESSOR_ARCEM: +- arc_cpu_string = "EM"; +- break; +- +- case PROCESSOR_ARCHS: +- arc_cpu_string = "HS"; +- break; +- +- default: +- gcc_unreachable (); +- } +- +- if (arc_tune == TUNE_NONE) +- arc_tune = tune_dflt; + /* Note: arc_multcost is only used in rtx_cost if speed is true. */ + if (arc_multcost < 0) + switch (arc_tune) +@@ -739,18 +712,10 @@ arc_init (void) + break; + } + +- /* Support mul64 generation only for ARC600. */ +- if (TARGET_MUL64_SET && (!TARGET_ARC600_FAMILY)) +- error ("-mmul64 not supported for ARC700 or ARCv2"); +- + /* MPY instructions valid only for ARC700 or ARCv2. */ + if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY) + error ("-mno-mpy supported only for ARC700 or ARCv2"); + +- /* mul/mac instructions only for ARC600. */ +- if (TARGET_MULMAC_32BY16_SET && (!TARGET_ARC600_FAMILY)) +- error ("-mmul32x16 supported only for ARC600 or ARC601"); +- + if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR) + error ("-mno-dpfp-lrsr supported only with -mdpfp"); + +@@ -763,23 +728,11 @@ arc_init (void) + if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY) + error ("-mspfp_fast not available on ARC600 or ARC601"); + +- /* FPX-3. No FPX extensions on pre-ARC600 cores. */ +- if ((TARGET_DPFP || TARGET_SPFP) +- && (!TARGET_ARCOMPACT_FAMILY && !TARGET_EM)) +- error ("FPX extensions not available on pre-ARC600 cores"); +- +- /* FPX-4. No FPX extensions mixed with FPU extensions for ARC HS +- cpus. */ +- if ((TARGET_DPFP || TARGET_SPFP) +- && TARGET_HARD_FLOAT +- && TARGET_HS) ++ /* FPX-4. No FPX extensions mixed with FPU extensions. */ ++ if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP) ++ && TARGET_HARD_FLOAT) + error ("No FPX/FPU mixing allowed"); + +- /* Only selected multiplier configurations are available for HS. */ +- if (TARGET_HS && ((arc_mpy_option > 2 && arc_mpy_option < 7) +- || (arc_mpy_option == 1))) +- error ("This multiplier configuration is not available for HS cores"); +- + /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */ + if (flag_pic && TARGET_ARC600_FAMILY) + { +@@ -789,26 +742,6 @@ arc_init (void) + flag_pic = 0; + } + +- if (TARGET_ATOMIC && !(TARGET_ARC700 || TARGET_HS)) +- error ("-matomic is only supported for ARC700 or ARC HS cores"); +- +- /* ll64 ops only available for HS. */ +- if (TARGET_LL64 && !TARGET_HS) +- error ("-mll64 is only supported for ARC HS cores"); +- +- /* FPU support only for V2. */ +- if (TARGET_HARD_FLOAT) +- { +- if (TARGET_EM +- && (arc_fpu_build & ~(FPU_SP | FPU_SF | FPU_SC | FPU_SD | FPX_DP))) +- error ("FPU double precision options are available for ARC HS only"); +- if (TARGET_HS && (arc_fpu_build & FPX_DP)) +- error ("FPU double precision assist " +- "options are not available for ARC HS"); +- if (!TARGET_HS && !TARGET_EM) +- error ("FPU options are available for ARCv2 architecture only"); +- } +- + arc_init_reg_tables (); + + /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */ +@@ -853,7 +786,92 @@ static void + arc_override_options (void) + { + if (arc_cpu == PROCESSOR_NONE) +- arc_cpu = PROCESSOR_ARC700; ++ arc_cpu = TARGET_CPU_DEFAULT; ++ ++ /* Set the default cpu options. */ ++ arc_selected_cpu = &arc_cpu_types[(int) arc_cpu]; ++ arc_selected_arch = &arc_arch_types[(int) arc_selected_cpu->arch]; ++ ++ /* Set the architectures. */ ++ switch (arc_selected_arch->arch) ++ { ++ case BASE_ARCH_em: ++ arc_arcem = true; ++ arc_cpu_string = "EM"; ++ break; ++ case BASE_ARCH_hs: ++ arc_archs = true; ++ arc_cpu_string = "HS"; ++ break; ++ case BASE_ARCH_700: ++ arc_arc700 = true; ++ arc_cpu_string = "ARC700"; ++ break; ++ case BASE_ARCH_6xx: ++ arc_cpu_string = "ARC600"; ++ if (arc_selected_cpu->flags & FL_BS) ++ arc_arc600 = true; ++ else ++ arc_arc601 = true; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ /* Set cpu flags accordingly to architecture/selected cpu. The cpu ++ specific flags are set in arc-common.c. The architecture forces ++ the default hardware configurations in, regardless what command ++ line options are saying. The CPU optional hw options can be ++ turned on or off. */ ++#define ARC_OPT(NAME, CODE, MASK, DOC) \ ++ do { \ ++ if ((arc_selected_cpu->flags & CODE) \ ++ && ((arc_seen_options & MASK) == 0)) \ ++ target_flags |= MASK; \ ++ if (arc_selected_arch->dflags & CODE) \ ++ target_flags |= MASK; \ ++ } while (0); ++#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \ ++ do { \ ++ if ((arc_selected_cpu->flags & CODE) \ ++ && (VAR == DEFAULT_##VAR)) \ ++ VAR = VAL; \ ++ if (arc_selected_arch->dflags & CODE) \ ++ VAR = VAL; \ ++ } while (0); ++ ++#include "arc-options.def" ++ ++#undef ARC_OPTX ++#undef ARC_OPT ++ ++ /* Check options against architecture options. Throw an error if ++ option is not allowed. */ ++#define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \ ++ do { \ ++ if ((VAR == VAL) \ ++ && (!(arc_selected_arch->flags & CODE))) \ ++ { \ ++ error ("%s is not available for %s architecture", \ ++ DOC, arc_selected_arch->name); \ ++ } \ ++ } while (0); ++#define ARC_OPT(NAME, CODE, MASK, DOC) \ ++ do { \ ++ if ((target_flags & MASK) \ ++ && (!(arc_selected_arch->flags & CODE))) \ ++ error ("%s is not available for %s architecture", \ ++ DOC, arc_selected_arch->name); \ ++ } while (0); ++ ++#include "arc-options.def" ++ ++#undef ARC_OPTX ++#undef ARC_OPT ++ ++ /* Set Tune option. */ ++ if (arc_tune == TUNE_NONE) ++ arc_tune = (enum attr_tune) arc_selected_cpu->tune; + + if (arc_size_opt_level == 3) + optimize_size = 1; +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index c02e1cd4c777..f1705d587d2f 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -28,6 +28,8 @@ along with GCC; see the file COPYING3. If not see + #ifndef GCC_ARC_H + #define GCC_ARC_H + ++#include ++ + /* Things to do: + + - incscc, decscc? +@@ -39,6 +41,10 @@ along with GCC; see the file COPYING3. If not see + #define SYMBOL_FLAG_LONG_CALL (SYMBOL_FLAG_MACH_DEP << 2) + #define SYMBOL_FLAG_CMEM (SYMBOL_FLAG_MACH_DEP << 3) + ++#ifndef TARGET_CPU_DEFAULT ++#define TARGET_CPU_DEFAULT PROCESSOR_arc700 ++#endif ++ + /* Check if this symbol has a long_call attribute in its declaration */ + #define SYMBOL_REF_LONG_CALL_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0) +@@ -74,9 +80,11 @@ along with GCC; see the file COPYING3. If not see + GNU_USER_TARGET_OS_CPP_BUILTINS (); \ + } \ + while (0) +-#endif + +-/* Match the macros used in the assembler. */ ++#endif /* DEFAULT_LIBC == LIBC_UCLIBC */ ++ ++/* Macros enabled by specific command line option. FIXME: to be ++ deprecatd. */ + #define CPP_SPEC "\ + %{msimd:-D__Xsimd} %{mno-mpy:-D__Xno_mpy} %{mswap:-D__Xswap} \ + %{mmin-max:-D__Xmin_max} %{mEA:-D__Xea} \ +@@ -85,34 +93,22 @@ along with GCC; see the file COPYING3. If not see + %{mdsp-packa:-D__Xdsp_packa} %{mcrc:-D__Xcrc} %{mdvbf:-D__Xdvbf} \ + %{mtelephony:-D__Xtelephony} %{mxy:-D__Xxy} %{mmul64: -D__Xmult32} \ + %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \ +-%{mcpu=NPS400:-D__NPS400__} \ +-%{mcpu=nps400:-D__NPS400__} \ +-" ++%{mcpu=nps400:-D__NPS400__}" + + #define CC1_SPEC "\ + %{EB:%{EL:%emay not use both -EB and -EL}} \ + %{EB:-mbig-endian} %{EL:-mlittle-endian} \ + " ++extern const char *arc_cpu_to_as (int argc, const char **argv); ++ ++#define EXTRA_SPEC_FUNCTIONS \ ++ { "cpu_to_as", arc_cpu_to_as }, ++ ++#define ASM_SPEC "%{mbig-endian|EB:-EB} %{EL} " \ ++ "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}" + +-#define ASM_DEFAULT "-mARC700 -mEA" +- +-#define ASM_SPEC "\ +-%{mbig-endian|EB:-EB} %{EL} \ +-%{mcpu=ARC600:-mARC600} \ +-%{mcpu=ARC601:-mARC601} \ +-%{mcpu=ARC700:-mARC700} \ +-%{mcpu=ARC700:-mEA} \ +-%{!mcpu=*:" ASM_DEFAULT "} \ +-%{mbarrel-shifter} %{mno-mpy} %{mmul64} %{mmul32x16:-mdsp-packa} %{mnorm} \ +-%{mswap} %{mEA} %{mmin-max} %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda} \ +-%{msimd} \ +-%{mmac-d16} %{mmac-24} %{mdsp-packa} %{mcrc} %{mdvbf} %{mtelephony} %{mxy} \ +-%{mcpu=ARC700|!mcpu=*:%{mlock}} \ +-%{mcpu=ARC700|!mcpu=*:%{mswape}} \ +-%{mcpu=ARC700|!mcpu=*:%{mrtsc}} \ +-%{mcpu=ARCHS:-mHS} \ +-%{mcpu=ARCEM:-mEM} \ +-%{matomic:-mlock}" ++#define OPTION_DEFAULT_SPECS \ ++ {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" } + + #if DEFAULT_LIBC == LIBC_UCLIBC + /* Note that the default is to link against dynamic libraries, if they are +@@ -196,17 +192,11 @@ along with GCC; see the file COPYING3. If not see + #define TARGET_MMEDIUM_CALLS_DEFAULT 0 + #endif + +-#define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \ +- "%{mARC600|mA6: -mcpu=ARC600 % ++ ++ 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" ++ ++/* Returns command line parameters to pass to as. */ ++ ++const char* ++arc_cpu_to_as (int argc, const char **argv) ++{ ++ const char *name = NULL; ++ const arc_cpu_t *arc_selected_cpu; ++ ++ /* No argument, check what is the default cpu. */ ++ if (argc == 0) ++ { ++ arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT]; ++ } ++ else ++ { ++ name = argv[0]; ++ for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name; ++ arc_selected_cpu++) ++ { ++ if (strcmp (arc_selected_cpu->name, name) == 0) ++ break; ++ } ++ } ++ ++ /* Checking the flags is only required with the old binutils ++ tools. */ ++ switch (arc_selected_cpu->arch) ++ { ++ case BASE_ARCH_em: ++ if (arc_selected_cpu->flags & FL_CD) ++ name = "-mcode-density"; ++ else ++ name = ""; ++ if (arc_selected_cpu->flags & FL_FPUDA) ++ name = concat ("-mfpuda ", name, NULL); ++ if (arc_selected_cpu->flags & FL_SPFP) ++ name = concat ("-mspfp ", name, NULL); ++ if (arc_selected_cpu->flags & FL_DPFP) ++ name = concat ("-mdpfp ", name, NULL); ++ return concat ("-mcpu=arcem ", name, NULL); ++ case BASE_ARCH_hs: ++ return "-mcpu=archs"; ++ case BASE_ARCH_700: ++ return "-mcpu=arc700 -mEA"; ++ case BASE_ARCH_6xx: ++ if (arc_selected_cpu->flags & FL_MUL64) ++ return "-mcpu=arc600 -mmul64 -mnorm"; ++ if (arc_selected_cpu->flags & FL_MUL32x16) ++ return "-mcpu=arc600 -mdsp-packa -mnorm"; ++ return "-mcpu=arc600 -mnorm"; ++ default: ++ gcc_unreachable (); ++ } ++ return NULL; ++} +diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk +new file mode 100644 +index 000000000000..61bda419c8a8 +--- /dev/null ++++ b/gcc/config/arc/genmultilib.awk +@@ -0,0 +1,204 @@ ++# Copyright (C) 2016 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 is using AVR's genmultilib.awk idea. ++# Transform CPU Information from avr-cpu.def to a ++# Representation that is understood by GCC's multilib Machinery. ++# ++# The Script works as a Filter from STDIN to STDOUT. ++# ++# FORMAT = "Makefile": Generate Makefile Snipet that sets some ++# MULTILIB_* Variables as needed. ++# ++################################################################## ++ ++BEGIN { ++ FS ="[(, \t)]+" ++ comment = 1 ++ n_cores = 0 ++ n_reuse = 0 ++} ++ ++################################################################## ++# Add some Comments to the generated Files and copy-paste ++# Copyright Notice from above. ++################################################################## ++/^#/ { ++ if (!comment) ++ next ++ else if (comment == 1) ++ { ++ if (FORMAT == "Makefile") ++ { ++ print "# Auto-generated Makefile Snip" ++ print "# Generated by : ./gcc/config/arc/genmultilib.awk" ++ print "# Generated from : ./gcc/config/arc/arc-cpu.def" ++ print "# Used by : tmake_file from Makefile and genmultilib" ++ print "" ++ } ++ } ++ ++ comment = 2; ++ ++ print ++} ++ ++/^$/ { ++ # The first empty line stops copy-pasting the GPL comments ++ # from this file to the generated file. ++ ++ comment = 0 ++} ++ ++ ++/^ARC_CPU/ { ++ name = $2 ++ # gsub ("\"", "", name) ++ ++ if ($4 != "0") ++ { ++ arch = $3 ++ if (arch == "6xx") ++ arch = 601 ++ ++ n = split ($4, cpu_flg, "|") ++ ++ line = "mcpu." arch ++ for (i = 1; i <= n; i++) ++ { ++ if (cpu_flg[i] == "FL_MPYOPT_0") ++ line = line "/mmpy-option.0" ++ else if (cpu_flg[i] == "FL_MPYOPT_1") ++ line = line "/mmpy-option.1" ++ else if (cpu_flg[i] == "FL_MPYOPT_2") ++ line = line "/mmpy-option.2" ++ else if (cpu_flg[i] == "FL_MPYOPT_3") ++ line = line "/mmpy-option.3" ++ else if (cpu_flg[i] == "FL_MPYOPT_4") ++ line = line "/mmpy-option.4" ++ else if (cpu_flg[i] == "FL_MPYOPT_5") ++ line = line "/mmpy-option.5" ++ else if (cpu_flg[i] == "FL_MPYOPT_6") ++ line = line "/mmpy-option.6" ++ else if (cpu_flg[i] == "FL_MPYOPT_7") ++ line = line "/mmpy-option.7" ++ else if (cpu_flg[i] == "FL_MPYOPT_8") ++ line = line "/mmpy-option.8" ++ else if (cpu_flg[i] == "FL_MPYOPT_9") ++ line = line "/mmpy-option.9" ++ else if (cpu_flg[i] == "FL_CD") ++ line = line "/mcode-density" ++ else if (cpu_flg[i] == "FL_BS") ++ line = line "/mbarrel-shifter" ++ else if (cpu_flg[i] == "FL_DIVREM") ++ line = line "/mdiv-rem" ++ else if (cpu_flg[i] == "FL_NORM" \ ++ || cpu_flg[i] == "FL_SWAP") # SWAP option goes into norm folder. ++ line = line "/mnorm" ++ else if (cpu_flg[i] == "FL_FPU_FPUS") ++ line = line "/mfpu.fpus" ++ else if (cpu_flg[i] == "FL_FPU_FPUDA") ++ line = line "/mfpu.fpuda" ++ else if (cpu_flg[i] == "FL_FPU_FPUD_ALL") ++ line = line "/mfpu.fpud_all" ++ else if (cpu_flg[i] == "FL_LL64") ++ line = line "/mll64" ++ else if (cpu_flg[i] == "FL_MUL64") ++ line = line "/mmul64" ++ else if (cpu_flg[i] == "FL_MUL32x16") ++ line = line "/mmul32x16" ++ else if (cpu_flg[i] == "FL_FPX_QUARK") ++ line = line "/quark" ++ else if (cpu_flg[i] == "FL_SPFP") ++ line = line "/spfp" ++ else if (cpu_flg[i] == "FL_DPFP") ++ line = line "/dpfp" ++ else ++ { ++ print "Don't know the flag " cpu_flg[i] > "/dev/stderr" ++ exit 1 ++ } ++ } ++ line = "mcpu." name "=" line ++ reuse[n_reuse] = line ++ n_reuse++ ++ } ++ ++ core = name ++ cores[n_cores] = core ++ n_cores++ ++} ++ ++################################################################## ++# ++# We gathered all the Information, now build/output the following: ++# ++# awk Variable target Variable FORMAT ++# ----------------------------------------------------------- ++# m_options <-> MULTILIB_OPTIONS Makefile ++# m_dirnames <-> MULTILIB_DIRNAMES " ++# ++################################################################## ++ ++END { ++ m_options = "\nMULTILIB_OPTIONS = " ++ m_dirnames = "\nMULTILIB_DIRNAMES =" ++ m_reuse = "\nMULTILIB_REUSE =" ++ ++ sep = "" ++ for (c = 0; c < n_cores; c++) ++ { ++ m_options = m_options sep "mcpu=" cores[c] ++ m_dirnames = m_dirnames " " cores[c] ++ sep = "/" ++ } ++ ++ sep = "" ++ for (c = 0; c < n_reuse; c++) ++ { ++ m_reuse = m_reuse sep reuse[c] ++ sep = "\nMULTILIB_REUSE +=" ++ } ++ ############################################################ ++ # Output that Stuff ++ ############################################################ ++ ++ if (FORMAT == "Makefile") ++ { ++ # Intended Target: ./gcc/config/arc/t-multilib ++ ++ print m_options ++ print m_dirnames ++ print m_reuse ++ ++ ############################################################ ++ # Legacy Aliases ++ ############################################################ ++ ++ print "" ++ print "# Aliases:" ++ print "MULTILIB_MATCHES = mcpu?arc600=mcpu?ARC600" ++ print "MULTILIB_MATCHES += mcpu?arc600=mARC600" ++ print "MULTILIB_MATCHES += mcpu?arc600=mA6" ++ print "MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601" ++ print "MULTILIB_MATCHES += mcpu?arc700=mA7" ++ print "MULTILIB_MATCHES += mcpu?arc700=mARC700" ++ } ++} +diff --git a/gcc/config/arc/genoptions.awk b/gcc/config/arc/genoptions.awk +new file mode 100644 +index 000000000000..816db6e83b92 +--- /dev/null ++++ b/gcc/config/arc/genoptions.awk +@@ -0,0 +1,85 @@ ++# Copyright (C) 2016 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 is using AVR's genmultilib.awk idea. ++# ++################################################################## ++ ++BEGIN { ++ FS ="[(, \t)]+" ++ comment = 1 ++ n_cores = 0 ++} ++ ++################################################################## ++# Add some Comments to the generated Files and copy-paste ++# Copyright Notice from above. ++################################################################## ++/^#/ { ++ if (!comment) ++ next ++ else if (comment == 1) ++ { ++ if (FORMAT == "Makefile") ++ { ++ print "; Auto-generated Makefile Snip" ++ print "; Generated by : ./gcc/config/arc/genoptions.awk" ++ print "; Generated from : ./gcc/config/arc/arc-cpu.def" ++ print ";" ++ } ++ } ++ ++ comment = 2; ++ ++ gsub ("^#", ";", $0) ++ print ++} ++ ++/^$/ { ++ # The first empty line stops copy-pasting the GPL comments ++ # from this file to the generated file. ++ comment = 0 ++} ++ ++/^ARC_CPU/ { ++ name = $2 ++ cores[n_cores] = name; ++ n_cores++ ++} ++ ++END { ++ m_option = "" ++ for (c = 0; c < n_cores; c++) ++ { ++ m_options = m_options "EnumValue\nEnum(processor_type) String(" cores[c] ") Value(PROCESSOR_" cores[c] ")\n\n" ++ } ++ ++ ############################################################ ++ # Output that Stuff ++ ############################################################ ++ ++ if (FORMAT == "Makefile") ++ { ++ print "\nEnum" ++ print "Name(processor_type) Type(enum processor_type)" ++ print "Known ARC CPUs (for use with the -mcpu= option):\n" ++ print m_options ++ } ++} +diff --git a/gcc/config/arc/t-arc b/gcc/config/arc/t-arc +index 4252e73cabb5..f8e0b54f1dfc 100644 +--- a/gcc/config/arc/t-arc ++++ b/gcc/config/arc/t-arc +@@ -19,11 +19,30 @@ + + TM_H += $(srcdir)/config/arc/arc-c.def + ++driver-arc.o: $(srcdir)/config/arc/driver-arc.c \ ++ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) ++ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< ++ + arc-c.o: $(srcdir)/config/arc/arc-c.c $(CONFIG_H) $(SYSTEM_H) \ + $(TREE_H) $(TM_H) $(TM_P_H) coretypes.h + $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ + $(srcdir)/config/arc/arc-c.c + ++#Run `arc-cpus` if you changed something in arc-cpus.def ++ ++.PHONY: arc-cpus ++ ++arc-cpus: $(srcdir)/config/arc/t-multilib \ ++ $(srcdir)/config/arc/arc-tables.opt ++ ++$(srcdir)/config/arc/t-multilib: $(srcdir)/config/arc/genmultilib.awk \ ++ $(srcdir)/config/arc/arc-cpus.def ++ $(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@ ++ ++$(srcdir)/config/arc/arc-tables.opt: $(srcdir)/config/arc/genoptions.awk \ ++ $(srcdir)/config/arc/arc-cpus.def ++ $(AWK) -f $< -v FORMAT=Makefile $< $(srcdir)/config/arc/arc-cpus.def > $@ ++ + # Local Variables: + # mode: Makefile + # End: +diff --git a/gcc/config/arc/t-arc-newlib b/gcc/config/arc/t-arc-newlib +deleted file mode 100644 +index c49a3fcc146f..000000000000 +--- a/gcc/config/arc/t-arc-newlib ++++ /dev/null +@@ -1,46 +0,0 @@ +-# GCC Makefile fragment for Synopsys DesignWare ARC with newlib. +- +-# Copyright (C) 2007-2016 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 +-# . +- +-MULTILIB_OPTIONS=mcpu=ARC600/mcpu=ARC601/mcpu=ARC700/mcpu=ARCEM/mcpu=ARCHS mmul64/mmul32x16 mnorm +-MULTILIB_DIRNAMES=arc600 arc601 arc700 em hs mul64 mul32x16 norm +-# +-# Aliases: +-MULTILIB_MATCHES = mcpu?ARC600=mcpu?arc600 +-MULTILIB_MATCHES += mcpu?ARC600=mARC600 +-MULTILIB_MATCHES += mcpu?ARC600=mA6 +-MULTILIB_MATCHES += mcpu?ARC600=mno-mpy +-MULTILIB_MATCHES += mcpu?ARC601=mcpu?arc601 +-MULTILIB_MATCHES += mcpu?ARC700=mA7 +-MULTILIB_MATCHES += mcpu?ARC700=mARC700 +-MULTILIB_MATCHES += mcpu?ARC700=mcpu?arc700 +-MULTILIB_MATCHES += mcpu?ARCEM=mcpu?arcem +-MULTILIB_MATCHES += mcpu?ARCHS=mcpu?archs +-MULTILIB_MATCHES += EL=mlittle-endian +-MULTILIB_MATCHES += EB=mbig-endian +-# +-# These don't make sense for the ARC700 default target: +-MULTILIB_EXCEPTIONS=mmul64* mmul32x16* norm* +-# And neither of the -mmul* options make sense without -mnorm: +-MULTILIB_EXCLUSIONS=mARC600/mmul64/!mnorm mcpu=ARC601/mmul64/!mnorm mARC600/mmul32x16/!mnorm +-# Exclusions for ARC700 +-MULTILIB_EXCEPTIONS += mcpu=ARC700/mnorm* mcpu=ARC700/mmul64* mcpu=ARC700/mmul32x16* +-# Exclusions for ARCv2EM +-MULTILIB_EXCEPTIONS += mcpu=ARCEM/mmul64* mcpu=ARCEM/mmul32x16* +-# Exclusions for ARCv2HS +-MULTILIB_EXCEPTIONS += mcpu=ARCHS/mmul64* mcpu=ARCHS/mmul32x16* mcpu=ARCHS/mnorm* +diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib +new file mode 100644 +index 000000000000..1407bdf0d82c +--- /dev/null ++++ b/gcc/config/arc/t-multilib +@@ -0,0 +1,51 @@ ++# Auto-generated Makefile Snip ++# Generated by : ./gcc/config/arc/genmultilib.awk ++# Generated from : ./gcc/config/arc/arc-cpu.def ++# Used by : tmake_file from Makefile and genmultilib ++ ++# Copyright (C) 2016 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 ++# . ++ ++MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400 ++ ++MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400 ++ ++MULTILIB_REUSE =mcpu.arcem=mcpu.em/mmpy-option.2/mcode-density/mbarrel-shifter ++MULTILIB_REUSE +=mcpu.em4=mcpu.em/mcode-density ++MULTILIB_REUSE +=mcpu.em4_dmips=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter ++MULTILIB_REUSE +=mcpu.em4_fpus=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpus ++MULTILIB_REUSE +=mcpu.em4_fpuda=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpuda ++MULTILIB_REUSE +=mcpu.archs=mcpu.hs/mmpy-option.2/mdiv-rem/mll64 ++MULTILIB_REUSE +=mcpu.hs34=mcpu.hs/mmpy-option.2 ++MULTILIB_REUSE +=mcpu.hs38=mcpu.hs/mmpy-option.9/mdiv-rem/mll64 ++MULTILIB_REUSE +=mcpu.hs38_linux=mcpu.hs/mmpy-option.9/mdiv-rem/mll64/mfpu.fpud_all ++MULTILIB_REUSE +=mcpu.arc600=mcpu.601/mbarrel-shifter ++MULTILIB_REUSE +=mcpu.arc600_norm=mcpu.601/mbarrel-shifter/mnorm ++MULTILIB_REUSE +=mcpu.arc600_mul64=mcpu.601/mbarrel-shifter/mnorm/mmul64 ++MULTILIB_REUSE +=mcpu.arc600_mul32x16=mcpu.601/mbarrel-shifter/mnorm/mmul32x16 ++MULTILIB_REUSE +=mcpu.arc601_norm=mcpu.601/mnorm ++MULTILIB_REUSE +=mcpu.arc601_mul64=mcpu.601/mnorm/mmul64 ++MULTILIB_REUSE +=mcpu.arc601_mul32x16=mcpu.601/mnorm/mmul32x16 ++ ++# Aliases: ++MULTILIB_MATCHES = mcpu?arc600=mcpu?ARC600 ++MULTILIB_MATCHES += mcpu?arc600=mARC600 ++MULTILIB_MATCHES += mcpu?arc600=mA6 ++MULTILIB_MATCHES += mcpu?arc601=mcpu?ARC601 ++MULTILIB_MATCHES += mcpu?arc700=mA7 ++MULTILIB_MATCHES += mcpu?arc700=mARC700 +diff --git a/gcc/config/arc/t-arc-uClibc b/gcc/config/arc/t-uClibc +similarity index 100% +rename from gcc/config/arc/t-arc-uClibc +rename to gcc/config/arc/t-uClibc +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index e6e725ec1c01..a3fa950d064b 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -13230,29 +13230,88 @@ values for @var{cpu} are + @table @samp + @opindex mA6 + @opindex mARC600 +-@item ARC600 + @item arc600 + Compile for ARC600. Aliases: @option{-mA6}, @option{-mARC600}. + +-@item ARC601 + @item arc601 + @opindex mARC601 + Compile for ARC601. Alias: @option{-mARC601}. + +-@item ARC700 + @item arc700 + @opindex mA7 + @opindex mARC700 + Compile for ARC700. Aliases: @option{-mA7}, @option{-mARC700}. + This is the default when configured with @option{--with-cpu=arc700}@. + +-@item ARCEM + @item arcem + Compile for ARC EM. + +-@item ARCHS + @item archs + Compile for ARC HS. ++ ++@item em ++@opindex em ++Compile for ARC EM cpu with no hardware extension. ++ ++@item em4 ++@opindex em4 ++Compile for ARC EM4 cpu. ++ ++@item em4_dmips ++@opindex em4_dmips ++Compile for ARC EM4 DMIPS cpu. ++ ++@item em4_fpus ++@opindex em4_pus ++Compile for ARC EM4 DMIPS cpu with single precision floating point ++extension. ++ ++@item em4_fpuda ++@opindex em4_fpuda ++Compile for ARC EM4 DMIPS cpu with single precision floating point and ++double assists instructions. ++ ++@item hs ++@opindex hs ++Compile for ARC HS cpu with no hardware extension, except the atomic ++instructions. ++ ++@item hs34 ++@opindex hs34 ++Compile for ARC HS34 cpu. ++ ++@item hs38 ++@opindex hs38 ++Compile for ARC HS38 cpu. ++ ++@item hs38_linux ++@opindex hs38_linux ++Compile for ARC HS38 cpu with all hardware extensions on. ++ ++@item arc600_norm ++@opindex arc600_norm ++Compile for ARC 600 cpu with norm instruction enabled. ++ ++@item arc600_mul32x16 ++@opindex arc600_mul32x16 ++Compile for ARC 600 cpu with norm and mul32x16 instructions enabled. ++ ++@item arc600_mul64 ++@opindex arc600_mul64 ++Compile for ARC 600 cpu with norm and mul64 instructions enabled. ++ ++@item arc601_norm ++@opindex arc601_norm ++Compile for ARC 601 cpu with norm instruction enabled. ++ ++@item arc601_mul32x16 ++@opindex arc601_mul32x16 ++Compile for ARC 601 cpu with norm and mul32x16 instructions enabled. ++ ++@item arc601_mul64 ++@opindex arc601_mul64 ++Compile for ARC 601 cpu with norm and mul64 instructions enabled. ++ + @end table + + @item -mdpfp +@@ -13279,7 +13338,8 @@ supported. This is always enabled for @option{-mcpu=ARC700}. + + @item -mno-mpy + @opindex mno-mpy +-Do not generate mpy instructions for ARC700. ++Do not generate mpy instructions for ARC700. This instruction is ++deprecated. + + @item -mmul32x16 + @opindex mmul32x16 +@@ -13486,12 +13546,14 @@ define preprocessor macro symbols. + @item -mdsp-packa + @opindex mdsp-packa + Passed down to the assembler to enable the DSP Pack A extensions. +-Also sets the preprocessor symbol @code{__Xdsp_packa}. ++Also sets the preprocessor symbol @code{__Xdsp_packa}. This option is ++deprecated. + + @item -mdvbf + @opindex mdvbf + Passed down to the assembler to enable the dual viterbi butterfly +-extension. Also sets the preprocessor symbol @code{__Xdvbf}. ++extension. Also sets the preprocessor symbol @code{__Xdvbf}. This ++option is deprecated. + + @c ARC700 4.10 extension instruction + @item -mlock +@@ -13503,19 +13565,19 @@ Conditional extension. Also sets the preprocessor symbol + @item -mmac-d16 + @opindex mmac-d16 + Passed down to the assembler. Also sets the preprocessor symbol +-@code{__Xxmac_d16}. ++@code{__Xxmac_d16}. This option is deprecated. + + @item -mmac-24 + @opindex mmac-24 + Passed down to the assembler. Also sets the preprocessor symbol +-@code{__Xxmac_24}. ++@code{__Xxmac_24}. This option is deprecated. + + @c ARC700 4.10 extension instruction + @item -mrtsc + @opindex mrtsc + Passed down to the assembler to enable the 64-bit Time-Stamp Counter + extension instruction. Also sets the preprocessor symbol +-@code{__Xrtsc}. ++@code{__Xrtsc}. This option is deprecated. + + @c ARC700 4.10 extension instruction + @item -mswape +@@ -13528,7 +13590,7 @@ extension instruction. Also sets the preprocessor symbol + @opindex mtelephony + Passed down to the assembler to enable dual and single operand + instructions for telephony. Also sets the preprocessor symbol +-@code{__Xtelephony}. ++@code{__Xtelephony}. This option is deprecated. + + @item -mxy + @opindex mxy +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0023-ARC-Various-small-miscellaneous-fixes.patch b/toolchain/gcc/patches/6.3.0/0023-ARC-Various-small-miscellaneous-fixes.patch new file mode 100644 index 0000000..2853698 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0023-ARC-Various-small-miscellaneous-fixes.patch @@ -0,0 +1,243 @@ +From 7659e01377a3f5bbfbce653f59e0a67538fe25d1 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 4 May 2016 17:33:42 +0200 +Subject: [PATCH 23/89] [ARC] Various small miscellaneous fixes. + +gcc/ +2016-05-09 Claudiu Zissulescu + + * config/arc/arc.md (movsi_insn): Disable unsupported move + instructions for ARCv2 cores. + * config/arc/arc.h (SHIFT_COUNT_TRUNCATED): Define to one. + (LINK_COMMAND_SPEC): Remove. +--- + gcc/config/arc/arc.c | 5 +---- + gcc/config/arc/arc.h | 27 +++------------------------ + gcc/config/arc/arc.md | 35 +++++++++++++++++++---------------- + gcc/config/arc/constraints.md | 3 ++- + gcc/config/arc/fpu.md | 4 +++- + gcc/config/arc/fpx.md | 26 ++++++++++++-------------- + 6 files changed, 40 insertions(+), 60 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 985df8151d74..0830af3cbef6 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -9025,10 +9025,7 @@ arc_process_double_reg_moves (rtx *operands) + rtx srcLow = simplify_gen_subreg (SImode, src, DFmode, + TARGET_BIG_ENDIAN ? 4 : 0); + +- emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode, +- gen_rtvec (3, dest, srcHigh, srcLow), +- VUNSPEC_ARC_DEXCL_NORES)); +- ++ emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow)); + } + else + gcc_unreachable (); +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index f1705d587d2f..f8f195d70153 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -124,24 +124,6 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + %{!marclinux*: %{pg|p|profile:-marclinux_prof;: -marclinux}} \ + %{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \ + %{shared:-shared}" +-/* Like the standard LINK_COMMAND_SPEC, but add %G when building +- a shared library with -nostdlib, so that the hidden functions of libgcc +- will be incorporated. +- N.B., we don't want a plain -lgcc, as this would lead to re-exporting +- non-hidden functions, so we have to consider libgcc_s.so.* first, which in +- turn should be wrapped with --as-needed. */ +-#define LINK_COMMAND_SPEC "\ +-%{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ +- %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ +- %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ +- %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\ +- %{fopenacc|fopenmp|%:gt(%{ftree-parallelize-loops=*:%*} 1):\ +- %:include(libgomp.spec)%(link_gomp)}\ +- %(mflib)\ +- %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\ +- %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\ +- %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}" +- + #else + #define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}\ + %{pg|p:-marcelf_prof;mA7|mARC700|mcpu=arc700|mcpu=ARC700: -marcelf}" +@@ -1563,13 +1545,10 @@ extern int arc_return_address_regs[4]; + /* Undo the effects of the movmem pattern presence on STORE_BY_PIECES_P . */ + #define MOVE_RATIO(SPEED) ((SPEED) ? 15 : 3) + +-/* Define this to be nonzero if shift instructions ignore all but the low-order +- few bits. Changed from 1 to 0 for rotate pattern testcases +- (e.g. 20020226-1.c). This change truncates the upper 27 bits of a word +- while rotating a word. Came to notice through a combine phase +- optimization viz. a << (32-b) is equivalent to a << (-b). ++/* Define this to be nonzero if shift instructions ignore all but the ++ low-order few bits. + */ +-#define SHIFT_COUNT_TRUNCATED 0 ++#define SHIFT_COUNT_TRUNCATED 1 + + /* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits + is done just by pretending it is already truncated. */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 5accf4a479b4..c86fc02c8240 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -699,9 +699,9 @@ + ; the iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . +-(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 +- [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") +- (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] ++(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 ++ [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") ++ (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hPCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || (CONSTANT_P (operands[1]) +@@ -746,7 +746,7 @@ + ; of Crr to 4. + (set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8") + (set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) ++ (set_attr "cpu_facility" "av1,av1,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) + + ;; Sometimes generated by the epilogue code. We don't want to + ;; recognize these addresses in general, because the limm is costly, +@@ -1083,12 +1083,9 @@ + (match_operand:DI 1 "general_operand" ""))] + "" + " +-{ +- /* Everything except mem = const or mem = mem can be done easily. */ +- +- if (GET_CODE (operands[0]) == MEM) +- operands[1] = force_reg (DImode, operands[1]); +-}") ++ if (prepare_move_operands (operands, DImode)) ++ DONE; ++ ") + + (define_insn_and_split "*movdi_insn" + [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r,m") +@@ -1135,7 +1132,7 @@ + ;; Floating point move insns. + + (define_expand "movsf" +- [(set (match_operand:SF 0 "general_operand" "") ++ [(set (match_operand:SF 0 "move_dest_operand" "") + (match_operand:SF 1 "general_operand" ""))] + "" + "if (prepare_move_operands (operands, SFmode)) DONE;") +@@ -1156,7 +1153,7 @@ + (set_attr "iscompact" "true,false,false,false,false")]) + + (define_expand "movdf" +- [(set (match_operand:DF 0 "nonimmediate_operand" "") ++ [(set (match_operand:DF 0 "move_dest_operand" "") + (match_operand:DF 1 "general_operand" ""))] + "" + "if (prepare_move_operands (operands, DFmode)) DONE;") +@@ -1226,12 +1223,18 @@ + ; second time to put back the contents which the first DEXCLx + ; will have overwritten + ; dexcl2 r0, r1, r0 +- (set (match_dup 4) ; aka r0result +- ; aka DF, r1, r0 +- (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL )) ++ (parallel [ ++ (set (match_dup 4) ; aka r0result ++ ; aka DF, r1, r0 ++ (unspec_volatile:SI [(match_dup 5) (match_dup 4)] ++ VUNSPEC_ARC_DEXCL)) ++ (clobber (match_dup 1)) ++ ]) + ; Generate the second, which makes sure operand5 and operand4 values + ; are put back in the Dx register properly. +- (unspec_volatile:SI [(match_dup 1) (match_dup 5) (match_dup 4)] VUNSPEC_ARC_DEXCL_NORES ) ++ (set (match_dup 1) (unspec_volatile:DF ++ [(match_dup 5) (match_dup 4)] ++ VUNSPEC_ARC_DEXCL_NORES)) + + ; Note: we cannot use a (clobber (match_scratch)) here because + ; the combine pass will end up replacing uses of it with 0 +diff --git a/gcc/config/arc/constraints.md b/gcc/config/arc/constraints.md +index b7bf2d39c4e8..8eccb2fdfe37 100644 +--- a/gcc/config/arc/constraints.md ++++ b/gcc/config/arc/constraints.md +@@ -256,7 +256,8 @@ + "@internal + constant for a highpart that can be checked with a shift (asr.f 0,rn,m)" + (and (match_code "const_int") +- (match_test "IS_POWEROF2_P (-ival)"))) ++ (match_test "IS_POWEROF2_P (-ival)") ++ (match_test "TARGET_BARREL_SHIFTER"))) + + (define_constraint "Clo" + "@internal +diff --git a/gcc/config/arc/fpu.md b/gcc/config/arc/fpu.md +index 9b0a65d93863..1050cabef62d 100644 +--- a/gcc/config/arc/fpu.md ++++ b/gcc/config/arc/fpu.md +@@ -197,7 +197,9 @@ + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (div:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] +- "TARGET_FP_SP_SQRT" ++ "TARGET_FP_SP_SQRT ++ && (register_operand (operands[1], SFmode) ++ || register_operand (operands[2], SFmode))" + "fsdiv%? %0,%1,%2" + [(set_attr "length" "4,4,8,8,8") + (set_attr "iscompact" "false") +diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md +index 2e11157cabfb..9ed2b7c683ab 100644 +--- a/gcc/config/arc/fpx.md ++++ b/gcc/config/arc/fpx.md +@@ -168,28 +168,26 @@ + (set_attr "type" "lr")] + ) + +- + (define_insn "*dexcl_3op_peep2_insn" + [(set (match_operand:SI 0 "dest_reg_operand" "=r") ; not register_operand, to accept SUBREG +- (unspec_volatile:SI [ +- (match_operand:DF 1 "arc_double_register_operand" "D") +- (match_operand:SI 2 "shouldbe_register_operand" "r") ; r1 +- (match_operand:SI 3 "shouldbe_register_operand" "r") ; r0 +- ] VUNSPEC_ARC_DEXCL )) +- ] ++ (unspec_volatile:SI ++ [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 ++ (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 ++ ] VUNSPEC_ARC_DEXCL )) ++ (clobber (match_operand:DF 3 "arc_double_register_operand" "=&D"))] + "TARGET_DPFP" +- "dexcl%F1 %0, %2, %3" ++ "dexcl%F3 %0, %1, %2" + [(set_attr "type" "move") + (set_attr "length" "4")] + ) + + ;; version which will not overwrite operand0 +-(define_insn "*dexcl_3op_peep2_insn_nores" +- [ (unspec_volatile:SI [ +- (match_operand:DF 0 "arc_double_register_operand" "D") +- (match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 +- (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 +- ] VUNSPEC_ARC_DEXCL_NORES ) ++(define_insn "dexcl_2op" ++ [(set (match_operand:DF 0 "arc_double_register_operand" "=D") ++ (unspec_volatile:DF ++ [(match_operand:SI 1 "shouldbe_register_operand" "r") ; r1 ++ (match_operand:SI 2 "shouldbe_register_operand" "r") ; r0 ++ ] VUNSPEC_ARC_DEXCL_NORES)) + ] + "TARGET_DPFP" + "dexcl%F0 0, %1, %2" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0024-ARC-Disable-compact-casesi-patterns-for-arcv2.patch b/toolchain/gcc/patches/6.3.0/0024-ARC-Disable-compact-casesi-patterns-for-arcv2.patch new file mode 100644 index 0000000..3e2f077 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0024-ARC-Disable-compact-casesi-patterns-for-arcv2.patch @@ -0,0 +1,50 @@ +From 0f8cd686af4d8a438334fec2ea54a0828aa80d7c Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 4 May 2016 17:34:25 +0200 +Subject: [PATCH 24/89] [ARC] Disable compact casesi patterns for arcv2 + +gcc/ +2016-05-09 Claudiu Zissulescu + + * common/config/arc/arc-common.c (arc_option_optimization_table): + Remove compact casesi option. + * config/arc/arc.c (arc_override_options): Use compact casesi + option only for pre-ARCv2 cores. +--- + gcc/common/config/arc/arc-common.c | 1 - + gcc/config/arc/arc.c | 7 +++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c +index 0141e3d6a23c..289886006380 100644 +--- a/gcc/common/config/arc/arc-common.c ++++ b/gcc/common/config/arc/arc-common.c +@@ -57,7 +57,6 @@ static const struct default_options arc_option_optimization_table[] = + { OPT_LEVELS_ALL, OPT_mbbit_peephole, NULL, 1 }, + { OPT_LEVELS_SIZE, OPT_mq_class, NULL, 1 }, + { OPT_LEVELS_SIZE, OPT_mcase_vector_pcrel, NULL, 1 }, +- { OPT_LEVELS_SIZE, OPT_mcompact_casesi, NULL, 1 }, + { OPT_LEVELS_NONE, 0, NULL, 0 } + }; + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 0830af3cbef6..93c8841a1b2b 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -876,6 +876,13 @@ arc_override_options (void) + if (arc_size_opt_level == 3) + optimize_size = 1; + ++ /* Compact casesi is not a valid option for ARCv2 family, disable ++ it. */ ++ if (TARGET_V2) ++ TARGET_COMPACT_CASESI = 0; ++ else if (optimize_size == 1) ++ TARGET_COMPACT_CASESI = 1; ++ + if (flag_pic) + target_flags |= MASK_NO_SDATA_SET; + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0025-ARC-Add-support-for-QuarkSE-processor.patch b/toolchain/gcc/patches/6.3.0/0025-ARC-Add-support-for-QuarkSE-processor.patch new file mode 100644 index 0000000..1908141 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0025-ARC-Add-support-for-QuarkSE-processor.patch @@ -0,0 +1,429 @@ +From 6e34de3cf703f1db5c7aef2a47c6c86c0602cf26 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 25 May 2016 14:59:41 +0200 +Subject: [PATCH 25/89] [ARC] Add support for QuarkSE processor. + +gcc/ +2016-05-25 Claudiu Zissulescu + + * config/arc/arc-arches.def: Add FPX quarkse instruction as valid + for arcem. + * config/arc/arc-c.def (__ARC_FPX_QUARK__): Define. + * config/arc/arc-cpus.def (quarkse_em): Add. + * config/arc/arc-options.def (FL_FPX_QUARK, FL_QUARK): Likewise. + * config/arc/arc-opts.h (FPX_QK): Define. + * config/arc/arc-tables.opt: Regenerate. + * config/arc/arc.c (gen_compare_reg): Change. + (arc_register_move_cost): Avoid Dy,Dx moves. + * config/arc/arc.h (TARGET_HARD_FLOAT): Change. + (TARGET_FPX_QUARK, TARGET_FP_ASSIST): Define. + * config/arc/arc.md (divsf3, sqrtsf2, fix_truncsfsi2, floatsisf2): + New expands. + * config/arc/fpu.md (divsf3_fpu, sqrtsf2_fpu, floatsisf2_fpu) + (fix_truncsfsi2_fpu): Rename. + * config/arc/fpx.md (cmp_quark, cmpsf_quark_, cmpsf_quark_ord) + (cmpsf_quark_uneq, cmpsf_quark_eq, divsf3_quark, sqrtsf2_quark) + (fix_truncsfsi2_quark, floatsisf2_quark): New patterns. + * config/arc/t-multilib: Regenerate. +--- + gcc/config/arc/arc-arches.def | 2 +- + gcc/config/arc/arc-c.def | 1 + + gcc/config/arc/arc-cpus.def | 1 + + gcc/config/arc/arc-options.def | 2 + + gcc/config/arc/arc-opts.h | 2 + + gcc/config/arc/arc-tables.opt | 3 ++ + gcc/config/arc/arc.c | 22 +++++++++- + gcc/config/arc/arc.h | 12 +++-- + gcc/config/arc/arc.md | 46 ++++++++++++++++++++ + gcc/config/arc/fpu.md | 8 ++-- + gcc/config/arc/fpx.md | 99 ++++++++++++++++++++++++++++++++++++++++++ + gcc/config/arc/t-multilib | 5 ++- + 12 files changed, 188 insertions(+), 15 deletions(-) + +diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def +index da69a1a8230c..db96ce1241cb 100644 +--- a/gcc/config/arc/arc-arches.def ++++ b/gcc/config/arc/arc-arches.def +@@ -19,7 +19,7 @@ + + ARC_ARCH("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM \ + | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP \ +- | FL_SIMD | FL_FPUDA, 0) ++ | FL_SIMD | FL_FPUDA | FL_QUARK, 0) + ARC_ARCH("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD \ + | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP \ + | FL_FPUS | FL_FPUD, \ +diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def +index 4cfd7b6e35fd..fd643760d88e 100644 +--- a/gcc/config/arc/arc-c.def ++++ b/gcc/config/arc/arc-c.def +@@ -58,6 +58,7 @@ ARC_C_DEF ("__ARC_FPU_DP_DIV__", TARGET_FP_DP_SQRT) + ARC_C_DEF ("__ARC_FPU_SP_FMA__", TARGET_FP_SP_FUSED) + ARC_C_DEF ("__ARC_FPU_DP_FMA__", TARGET_FP_DP_FUSED) + ARC_C_DEF ("__ARC_FPU_ASSIST__", TARGET_FP_DP_AX) ++ARC_C_DEF ("__ARC_FPX_QUARK__", TARGET_FPX_QUARK) + + /* To be deprecated. */ + ARC_C_DEF ("__A6__", TARGET_ARC600) +diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def +index 6d93c89e04a4..8782bd5e9263 100644 +--- a/gcc/config/arc/arc-cpus.def ++++ b/gcc/config/arc/arc-cpus.def +@@ -23,6 +23,7 @@ ARC_CPU (em4, em, FL_CD, NONE) + ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE) + ARC_CPU (em4_fpus, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE) + ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE) ++ARC_CPU (quarkse_em, em, FL_MPYOPT_3|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPX_QUARK|FL_SPFP|FL_DPFP, NONE) + + ARC_CPU (hs, hs, 0, NONE) + ARC_CPU (archs, hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE) +diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def +index 3834894a0884..778f69d95afe 100644 +--- a/gcc/config/arc/arc-options.def ++++ b/gcc/config/arc/arc-options.def +@@ -59,10 +59,12 @@ ARC_OPTX (FL_FPU_FPUD, (1ULL << 34), arc_fpu_build, FPU_FPUD, "mfpu=fpud") + ARC_OPTX (FL_FPU_FPUD_DIV, (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV, "mfpu=fpud_div") + ARC_OPTX (FL_FPU_FPUD_FMA, (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA, "mfpu=fpud_fma") + ARC_OPTX (FL_FPU_FPUD_ALL, (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL, "mfpu=fpud_all") ++ARC_OPTX (FL_FPX_QUARK, (1ULL << 38), arc_fpu_build, FPX_QK, "quarkse fp") + + ARC_OPT (FL_FPUS, (0xFULL << 26), 0, "single precission floating point") + ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist") + ARC_OPT (FL_FPUD, (0xF0FULL << 26), 0, "double precission floating point") ++ARC_OPT (FL_QUARK, (1ULL << 38), 0, "Quark SE fp extension") + + /* Local Variables: */ + /* mode: c */ +diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h +index 81446b4a412a..819b97c299f6 100644 +--- a/gcc/config/arc/arc-opts.h ++++ b/gcc/config/arc/arc-opts.h +@@ -48,6 +48,8 @@ enum processor_type + #define FPU_DD 0x0080 + /* Double precision floating point assist operations. */ + #define FPX_DP 0x0100 ++/* Quark SE floating point instructions. */ ++#define FPX_QK 0x0200 + + /* fpus option combi. */ + #define FPU_FPUS (FPU_SP | FPU_SC) +diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt +index 0e7c50c7be78..41e325c91d57 100644 +--- a/gcc/config/arc/arc-tables.opt ++++ b/gcc/config/arc/arc-tables.opt +@@ -43,6 +43,9 @@ EnumValue + Enum(processor_type) String(em4_fpuda) Value(PROCESSOR_em4_fpuda) + + EnumValue ++Enum(processor_type) String(quarkse_em) Value(PROCESSOR_quarkse_em) ++ ++EnumValue + Enum(processor_type) String(hs) Value(PROCESSOR_hs) + + EnumValue +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 93c8841a1b2b..c2673334db5d 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1728,6 +1728,26 @@ gen_compare_reg (rtx comparison, machine_mode omode) + gen_rtx_REG (CC_FPXmode, 61), + const0_rtx))); + } ++ else if (TARGET_FPX_QUARK && (cmode == SFmode)) ++ { ++ switch (code) ++ { ++ case NE: case EQ: case GT: case UNLE: case GE: case UNLT: ++ case UNEQ: case LTGT: case ORDERED: case UNORDERED: ++ break; ++ case LT: case UNGE: case LE: case UNGT: ++ code = swap_condition (code); ++ tmp = x; ++ x = y; ++ y = tmp; ++ break; ++ default: ++ gcc_unreachable (); ++ } ++ ++ emit_insn (gen_cmp_quark (cc_reg, ++ gen_rtx_COMPARE (mode, x, y))); ++ } + else if (TARGET_HARD_FLOAT + && ((cmode == SFmode && TARGET_FP_SP_BASE) + || (cmode == DFmode && TARGET_FP_DP_BASE))) +@@ -7282,7 +7302,7 @@ arc_register_move_cost (machine_mode, + return 8; + + /* Force an attempt to 'mov Dy,Dx' to spill. */ +- if (TARGET_ARC700 && TARGET_DPFP ++ if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP + && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS) + return 100; + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index f8f195d70153..795831d2c810 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -197,12 +197,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + default for A7, and only for pre A7 cores when -mnorm is given. */ + #define TARGET_NORM (TARGET_ARC700 || TARGET_NORM_SET || TARGET_HS) + /* Indicate if an optimized floating point emulation library is available. */ +-#define TARGET_OPTFPE \ +- (TARGET_ARC700 \ +- /* We need a barrel shifter and NORM. */ \ +- || (TARGET_ARC600 && TARGET_NORM_SET) \ +- || TARGET_HS \ +- || (TARGET_EM && TARGET_NORM_SET && TARGET_BARREL_SHIFTER)) ++#define TARGET_OPTFPE (TARGET_ARC700 || TARGET_FPX_QUARK) + + /* Non-zero means the cpu supports swap instruction. This flag is set by + default for A7, and only for pre A7 cores when -mswap is given. */ +@@ -1704,7 +1699,7 @@ enum + + /* FPU defines. */ + /* Any FPU support. */ +-#define TARGET_HARD_FLOAT (arc_fpu_build != 0) ++#define TARGET_HARD_FLOAT ((arc_fpu_build & (FPU_SP | FPU_DP)) != 0) + /* Single precision floating point support. */ + #define TARGET_FP_SP_BASE ((arc_fpu_build & FPU_SP) != 0) + /* Double precision floating point support. */ +@@ -1723,5 +1718,8 @@ enum + #define TARGET_FP_DP_SQRT ((arc_fpu_build & FPU_DD) != 0) + /* Double precision floating point assist instruction support. */ + #define TARGET_FP_DP_AX ((arc_fpu_build & FPX_DP) != 0) ++/* Custom FP instructions used by QuarkSE EM cpu. */ ++#define TARGET_FPX_QUARK (TARGET_EM && TARGET_SPFP \ ++ && (arc_fpu_build == FPX_QK)) + + #endif /* GCC_ARC_H */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index c86fc02c8240..87e6a172a9a5 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -5983,6 +5983,52 @@ + gcc_unreachable (); + ") + ++;;div ++(define_expand "divsf3" ++ [(set (match_operand:SF 0 "register_operand" "") ++ (div:SF (match_operand:SF 1 "nonmemory_operand" "") ++ (match_operand:SF 2 "nonmemory_operand" "")))] ++ "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" ++ " ++ if (TARGET_FPX_QUARK) ++ { ++ operands[1] = force_reg (SFmode, operands[1]); ++ operands[2] = force_reg (SFmode, operands[2]); ++ } ++ else ++ { ++ if (!register_operand (operands[1], SFmode) ++ && !register_operand (operands[2], SFmode)) ++ operands[1] = force_reg (SFmode, operands[1]); ++ } ++ ") ++ ++;; Square root ++(define_expand "sqrtsf2" ++ [(set (match_operand:SF 0 "register_operand" "") ++ (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))] ++ "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" ++ " ++ if (TARGET_FPX_QUARK) ++ { ++ operands[1] = force_reg (SFmode, operands[1]); ++ } ++") ++ ++;; SF->SI (using rounding towards zero) ++(define_expand "fix_truncsfsi2" ++ [(set (match_operand:SI 0 "register_operand" "") ++ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" ""))))] ++ "TARGET_FPX_QUARK || TARGET_FP_SP_CONV" ++ "") ++ ++;; SI->SF ++(define_expand "floatsisf2" ++ [(set (match_operand:SF 0 "register_operand" "") ++ (float:SF (match_operand:SI 1 "register_operand" "")))] ++ "TARGET_FPX_QUARK || TARGET_FP_SP_CONV" ++ "") ++ + (define_expand "extzv" + [(set (match_operand:SI 0 "register_operand" "") + (zero_extract:SI (match_operand:SI 1 "register_operand" "") +diff --git a/gcc/config/arc/fpu.md b/gcc/config/arc/fpu.md +index 1050cabef62d..cc7902b568b9 100644 +--- a/gcc/config/arc/fpu.md ++++ b/gcc/config/arc/fpu.md +@@ -193,7 +193,7 @@ + (set_attr "type" "fpu")]) + + ;; Division +-(define_insn "divsf3" ++(define_insn "divsf3_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r,r,r,r") + (div:SF (match_operand:SF 1 "nonmemory_operand" "0,r,0,r,F") + (match_operand:SF 2 "nonmemory_operand" "r,r,F,F,r")))] +@@ -215,7 +215,7 @@ + ;; see pattern in arc.md + + ;; Square root +-(define_insn "sqrtsf2" ++(define_insn "sqrtsf2_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "r,F")))] + "TARGET_FP_SP_SQRT" +@@ -412,7 +412,7 @@ + ) + + ;; SI->SF +-(define_insn "floatsisf2" ++(define_insn "floatsisf2_fpu" + [(set (match_operand:SF 0 "register_operand" "=r,r") + (float:SF (match_operand:SI 1 "register_operand" "0,r")))] + "TARGET_FP_SP_CONV" +@@ -448,7 +448,7 @@ + ) + + ;; SF->SI (using rounding towards zero) +-(define_insn "fix_truncsfsi2" ++(define_insn "fix_truncsfsi2_fpu" + [(set (match_operand:SI 0 "register_operand" "=r,r") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "0,r"))))] + "TARGET_FP_SP_CONV" +diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md +index 9ed2b7c683ab..094319e1ce4f 100644 +--- a/gcc/config/arc/fpx.md ++++ b/gcc/config/arc/fpx.md +@@ -614,3 +614,102 @@ + [(set_attr "type" "dpfp_addsub") + (set_attr "length" "4,8,4,8") + (set_attr "cpu_facility" "*,*,fpx,fpx")]) ++ ++;; Intel QUARK SE extensions ++(define_mode_iterator QUARK_CMP [CC_FP_GT CC_FP_GE]) ++(define_mode_attr quark_cmp [(CC_FP_GT "gt") (CC_FP_GE "ge")]) ++ ++(define_expand "cmp_quark" ++ [(parallel [(set (match_operand 0 "") ++ (match_operand 1 "")) ++ (clobber (match_scratch:SI 2 ""))])] ++ "" ++ "") ++ ++(define_insn "*cmpsf_quark_" ++ [(set (reg:QUARK_CMP CC_REG) ++ (compare:QUARK_CMP (match_operand:SF 0 "register_operand" "r") ++ (match_operand:SF 1 "register_operand" "r"))) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_cmp\\t%2,%0,%1\\n\\trsub.f\\t0,%2,7\\n\\tcmp.nc\\t%2,1\\n\\tcmp.hi\\t%2,3" ++ [(set_attr "length" "16") ++ (set_attr "cond" "set") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "*cmpsf_quark_ord" ++ [(set (reg:CC_FP_ORD CC_REG) ++ (compare:CC_FP_ORD (match_operand:SF 0 "register_operand" "r") ++ (match_operand:SF 1 "register_operand" "r"))) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_cmp\\t%2,%0,%1\\n\\tadd.f\\t%2,%2,-8" ++ [(set_attr "length" "8") ++ (set_attr "cond" "set") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "*cmpsf_quark_uneq" ++ [(set (reg:CC_FP_UNEQ CC_REG) ++ (compare:CC_FP_UNEQ (match_operand:SF 0 "register_operand" "r") ++ (match_operand:SF 1 "register_operand" "r"))) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,6" ++ [(set_attr "length" "8") ++ (set_attr "cond" "set") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "*cmpsf_quark_eq" ++ [(set (reg:CC_Z CC_REG) ++ (compare:CC_Z (match_operand:SF 0 "register_operand" "r") ++ (match_operand:SF 1 "register_operand" "r"))) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_cmp\\t%2,%0,%1\\n\\ttst\\t%2,0x0E" ++ [(set_attr "length" "8") ++ (set_attr "cond" "set") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "*divsf3_quark" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (div:SF (match_operand:SF 1 "register_operand" "r") ++ (match_operand:SF 2 "register_operand" "r")))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_div\\t%0,%1,%2" ++ [(set_attr "length" "4") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "*sqrtsf2_quark" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (sqrt:SF (match_operand:SF 1 "register_operand" "r")))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_sqrt\\t%0,%1" ++ [(set_attr "length" "4") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++;; SF->SI (using rounding towards zero) ++(define_insn "*fix_truncsfsi2_quark" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "r"))))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_flt2i\\t%0,%1" ++ [(set_attr "length" "4") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++;; SI->SF ++(define_insn "*floatsisf2_quark" ++ [(set (match_operand:SF 0 "register_operand" "=r") ++ (float:SF (match_operand:SI 1 "register_operand" "r")))] ++ "TARGET_FPX_QUARK" ++ "dsp_fp_i2flt\\t%0,%1" ++ [(set_attr "length" "4") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ +diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib +index 1407bdf0d82c..0f1c398d61f8 100644 +--- a/gcc/config/arc/t-multilib ++++ b/gcc/config/arc/t-multilib +@@ -21,15 +21,16 @@ + # along with GCC; see the file COPYING3. If not see + # . + +-MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400 ++MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400 + +-MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400 ++MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400 + + MULTILIB_REUSE =mcpu.arcem=mcpu.em/mmpy-option.2/mcode-density/mbarrel-shifter + MULTILIB_REUSE +=mcpu.em4=mcpu.em/mcode-density + MULTILIB_REUSE +=mcpu.em4_dmips=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter + MULTILIB_REUSE +=mcpu.em4_fpus=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpus + MULTILIB_REUSE +=mcpu.em4_fpuda=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpuda ++MULTILIB_REUSE +=mcpu.quarkse_em=mcpu.em/mmpy-option.3/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/quark/spfp/dpfp + MULTILIB_REUSE +=mcpu.archs=mcpu.hs/mmpy-option.2/mdiv-rem/mll64 + MULTILIB_REUSE +=mcpu.hs34=mcpu.hs/mmpy-option.2 + MULTILIB_REUSE +=mcpu.hs38=mcpu.hs/mmpy-option.9/mdiv-rem/mll64 +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0026-ARC-libgcc-Add-support-for-QuarkSE-processor.patch b/toolchain/gcc/patches/6.3.0/0026-ARC-libgcc-Add-support-for-QuarkSE-processor.patch new file mode 100644 index 0000000..139bc84 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0026-ARC-libgcc-Add-support-for-QuarkSE-processor.patch @@ -0,0 +1,441 @@ +From 17c52f2269de4d875c04f6bc372387b730fe7aca Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 26 May 2016 11:08:52 +0200 +Subject: [PATCH 26/89] [ARC] [libgcc] Add support for QuarkSE processor. + +libgcc/ +2016-05-26 Claudiu Zissulescu + + * config/arc/dp-hack.h (ARC_OPTFPE): Define. + (__ARC_NORM__): Use instead ARC_OPTFPE. + * config/arc/fp-hack.h: Likewise. + * config/arc/lib1funcs.S (ARC_OPTFPE): Define. + (__ARC_MPY__): Use it insetead of __ARC700__ and __HS__. +--- + libgcc/config/arc/dp-hack.h | 12 +++-- + libgcc/config/arc/fp-hack.h | 8 +-- + libgcc/config/arc/lib1funcs.S | 120 ++++++++++++++++++++++-------------------- + 3 files changed, 74 insertions(+), 66 deletions(-) + +diff --git a/libgcc/config/arc/dp-hack.h b/libgcc/config/arc/dp-hack.h +index 3c727b122c0c..1f7f213288a2 100644 +--- a/libgcc/config/arc/dp-hack.h ++++ b/libgcc/config/arc/dp-hack.h +@@ -30,21 +30,23 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + + #define FINE_GRAINED_LIBRARIES + #define ARC_DP_DEBUG 1 +-#if !defined (__ARC_NORM__) || ARC_DP_DEBUG ++#define ARC_OPTFPE (defined (__ARC700__) || defined (__ARC_FPX_QUARK__)) ++ ++#if !ARC_OPTFPE || ARC_DP_DEBUG + #define L_pack_df + #define L_unpack_df + #define L_make_df + #define L_thenan_df + #define L_sf_to_df + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_addsub_df + #elif ARC_DP_DEBUG + #define L_addsub_df + #define __adddf3 __adddf3_c + #define __subdf3 __subdf3_c + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_mul_df + #define L_div_df + #elif (!defined (__ARC700__) && !defined (__ARC_MUL64__) \ +@@ -59,7 +61,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define L_div_df + #define __divdf3 __divdf3_c + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_df_to_sf + #define L_si_to_df + #define L_df_to_si +@@ -77,7 +79,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define L_usi_to_df + #define __floatunsidf __floatunsidf_c + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_fpcmp_parts_df + #define L_compare_df + #define L_eq_df +diff --git a/libgcc/config/arc/fp-hack.h b/libgcc/config/arc/fp-hack.h +index 30b547a38403..5144bb950960 100644 +--- a/libgcc/config/arc/fp-hack.h ++++ b/libgcc/config/arc/fp-hack.h +@@ -30,13 +30,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + + #define ARC_FP_DEBUG 1 + #define FINE_GRAINED_LIBRARIES +-#if !defined (__ARC_NORM__) || ARC_FP_DEBUG ++#define ARC_OPTFPE (defined (__ARC700__) || defined (__ARC_FPX_QUARK__)) ++ ++#if !ARC_OPTFPE || ARC_FP_DEBUG + #define L_pack_sf + #define L_unpack_sf + #define L_make_sf + #define L_thenan_sf + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_addsub_sf + #define L_mul_sf + #define L_div_sf +@@ -61,7 +63,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + #define L_usi_to_sf + #define __floatunsisf __floatunsisf_c + #endif +-#ifndef __ARC_NORM__ ++#if !ARC_OPTFPE + #define L_fpcmp_parts_sf + #define L_compare_sf + #define L_eq_sf +diff --git a/libgcc/config/arc/lib1funcs.S b/libgcc/config/arc/lib1funcs.S +index 1c8961cfb9dd..9bb25e0a90ed 100644 +--- a/libgcc/config/arc/lib1funcs.S ++++ b/libgcc/config/arc/lib1funcs.S +@@ -32,29 +32,29 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + This exception does not however invalidate any other reasons why + the executable file might be covered by the GNU General Public License. */ + +- ++ + /* ANSI concatenation macros. */ +- ++ + #define CONCAT1(a, b) CONCAT2(a, b) + #define CONCAT2(a, b) a ## b +- ++ + /* Use the right prefix for global labels. */ +- ++ + #define SYM(x) CONCAT1 (__USER_LABEL_PREFIX__, x) +- ++ + #ifndef WORKING_ASSEMBLER + #define abs_l abs + #define asl_l asl + #define mov_l mov + #endif +- ++ + #define FUNC(X) .type SYM(X),@function + #define HIDDEN_FUNC(X) FUNC(X)` .hidden X + #define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X + #define ENDFUNC(X) ENDFUNC0(X) + +- +- ++ ++ + #ifdef L_mulsi3 + .section .text + .align 4 +@@ -64,10 +64,10 @@ SYM(__mulsi3): + + /* This the simple version. + +- while (a) ++ while (a) + { + if (a & 1) +- r += b; ++ r += b; + a >>= 1; + b <<= 1; + } +@@ -132,7 +132,7 @@ SYM(__mulsi3): + add2.cs r0,r0,r1 + lsr.f r2,r2 + add3.cs r0,r0,r1 +- bne.d .Loop ++ bne.d .Loop + add3 r1,r3,r1 + j_s [blink] + ENDFUNC(__mulsi3) +@@ -143,17 +143,17 @@ SYM(__mulsi3): + .Lloop: + bbit0 r0,0,@.Ly + add_s r2,r2,r1 ; r += b +-.Ly: ++.Ly: + lsr_s r0,r0 ; a >>= 1 +- asl_s r1,r1 ; b <<= 1 +- brne_s r0,0,@.Lloop ++ asl_s r1,r1 ; b <<= 1 ++ brne_s r0,0,@.Lloop + .Ldone: + j_s.d [blink] + mov_s r0,r2 + ENDFUNC(__mulsi3) + /********************************************************/ + #endif +- ++ + #endif /* L_mulsi3 */ + + #ifdef L_umulsidi3 +@@ -178,10 +178,10 @@ SYM(__umulsi3_highpart): + + /* This the simple version. + +- while (a) ++ while (a) + { + if (a & 1) +- r += b; ++ r += b; + a >>= 1; + b <<= 1; + } +@@ -455,18 +455,18 @@ SYM(__udivmodsi4): + mov_s r2,1 ; bit = 1 + mov_s r3,0 ; res = 0 + .Lloop1: +- brhs r1,r0,@.Lloop2 ++ brhs r1,r0,@.Lloop2 + bbit1 r1,31,@.Lloop2 + asl_s r1,r1 ; den <<= 1 + b.d @.Lloop1 + asl_s r2,r2 ; bit <<= 1 + .Lloop2: +- brlo r0,r1,@.Lshiftdown ++ brlo r0,r1,@.Lshiftdown + sub_s r0,r0,r1 ; num -= den + or_s r3,r3,r2 ; res |= bit + .Lshiftdown: + lsr_s r2,r2 ; bit >>= 1 +- lsr_s r1,r1 ; den >>= 1 ++ lsr_s r1,r1 ; den >>= 1 + brne_s r2,0,@.Lloop2 + .Ldivmodend: + mov_s r1,r0 ; r1 = mod +@@ -785,15 +785,15 @@ __muldiv: + neg r4,r2 + ld.as r5,[pcl,r4] + abs_s r12,r0 +- bic.f 0,r2,r4 +- mpyhu.ne r12,r12,r5 ++ bic.f 0,r2,r4 ++ mpyhu.ne r12,r12,r5 + norm r3,r2 + xor.f 0,r0,r1 +- ; write port allocation stall +- rsub r3,r3,30 +- lsr r0,r12,r3 +- j_s.d [blink] +- neg.mi r0,r0 ++ ; write port allocation stall ++ rsub r3,r3,30 ++ lsr r0,r12,r3 ++ j_s.d [blink] ++ neg.mi r0,r0 + + .balign 4 + SYM(__divsi3): +@@ -876,7 +876,7 @@ SYM(__divsi3): + #endif /* ifndef __ARC700__ */ + ENDFUNC(__divsi3) + +- ++ + #endif /* L_divsi3 */ + + #ifdef L_umodsi3 +@@ -951,7 +951,7 @@ SYM(__modsi3): + .section .text + .align 4 + .global SYM (__clzsi2) +-SYM(__clzsi2): ++SYM(__clzsi2): + #ifdef __ARC_NORM__ + HIDDEN_FUNC(__clzsi2) + norm.f r0,r0 +@@ -1002,7 +1002,7 @@ SYM(__clzsi2): + + + ;;; MILLICODE THUNK LIB ;*************** +- ++ + ;;; .macro push_regs from, to, offset + ;;; st_s "\from", [sp, \offset] + ;;; .if \to-\from +@@ -1019,22 +1019,22 @@ SYM(__clzsi2): + ;;;; .set regno, \from+1 + ;;;; .set shift, 32 + ;;;; .set shift, shift - 1 +-;;;; # st_s %shift @3 lsl #shift ++;;;; # st_s %shift @3 lsl #shift + ;;;; .if \to-\from + ;;;; sum "(\from+1)", \to, "(\three)" +-;;;; .endif ++;;;; .endif + ;;;; .endm +-;;;; ++;;;; + ;;;; SUM 0,5, 9 +-;;;; +-; .altmacro ++;;;; ++; .altmacro + ;; .macro push_regs from=0, to=3, offset + ;; st_s r\from, [sp, \offset] + ;; .if \to-\from + ;; push_regs "\from+1 ",\to,"(\offset+4)" + ;; .endif + ;; .endm +-;; ++;; + ;; .macro expand_to_push from=13, to + ;; ; .section .text + ;; ; .align 4 +@@ -1042,11 +1042,11 @@ SYM(__clzsi2): + ;; ; .type foo, + ;; st_13_to_25: + ;; ; push_regs \from, \to, 0 +-;; push_regs 0,3 ; ++;; push_regs 0,3 ; + ;; .endm +-;; ++;; + ;; expand_to_push 13,18 +-;; ++;; + ;#endif + + #ifdef L_millicodethunk_st +@@ -1077,25 +1077,25 @@ SYM(__clzsi2): + .align 4 + SYM(__st_r13_to_r25): + st r25, [sp,48] +-SYM(__st_r13_to_r24): ++SYM(__st_r13_to_r24): + st r24, [sp,44] +-SYM(__st_r13_to_r23): ++SYM(__st_r13_to_r23): + st r23, [sp,40] +-SYM(__st_r13_to_r22): ++SYM(__st_r13_to_r22): + st r22, [sp,36] +-SYM(__st_r13_to_r21): ++SYM(__st_r13_to_r21): + st r21, [sp,32] +-SYM(__st_r13_to_r20): +- st r20, [sp,28] +-SYM(__st_r13_to_r19): ++SYM(__st_r13_to_r20): ++ st r20, [sp,28] ++SYM(__st_r13_to_r19): + st r19, [sp,24] +-SYM(__st_r13_to_r18): ++SYM(__st_r13_to_r18): + st r18, [sp,20] +-SYM(__st_r13_to_r17): ++SYM(__st_r13_to_r17): + st r17, [sp,16] +-SYM(__st_r13_to_r16): ++SYM(__st_r13_to_r16): + st r16, [sp,12] +-SYM(__st_r13_to_r15): ++SYM(__st_r13_to_r15): + #ifdef __ARC700__ + st r15, [sp,8] ; minimum function size to avoid stall: 6 bytes. + #else +@@ -1103,7 +1103,7 @@ SYM(__st_r13_to_r15): + #endif + st_s r14, [sp,4] + j_s.d [%blink] +- st_s r13, [sp,0] ++ st_s r13, [sp,0] + ENDFUNC(__st_r13_to_r15) + ENDFUNC(__st_r13_to_r16) + ENDFUNC(__st_r13_to_r17) +@@ -1121,7 +1121,7 @@ SYM(__st_r13_to_r15): + #ifdef L_millicodethunk_ld + .section .text + .align 4 +-; ================================== ++; ================================== + ; the loads + + .global SYM(__ld_r13_to_r15) +@@ -1157,7 +1157,7 @@ SYM(__ld_r13_to_r22): + SYM(__ld_r13_to_r21): + ld r21, [sp,32] + SYM(__ld_r13_to_r20): +- ld r20, [sp,28] ++ ld r20, [sp,28] + SYM(__ld_r13_to_r19): + ld r19, [sp,24] + SYM(__ld_r13_to_r18): +@@ -1226,7 +1226,7 @@ SYM(__ld_r13_to_r22_ret): + SYM(__ld_r13_to_r21_ret): + ld r21, [sp,32] + SYM(__ld_r13_to_r20_ret): +- ld r20, [sp,28] ++ ld r20, [sp,28] + SYM(__ld_r13_to_r19_ret): + ld r19, [sp,24] + SYM(__ld_r13_to_r18_ret): +@@ -1258,6 +1258,9 @@ SYM(__ld_r13_to_r14_ret): + + #endif /* L_millicodethunk_ret */ + ++#define ARC_OPTFPE (defined (__ARC700__) || defined (__ARC_FPX_QUARK__)) ++ ++#if ARC_OPTFPE + #ifdef L_adddf3 + #ifdef __ARC_NORM__ + #include "ieee-754/adddf3.S" +@@ -1265,7 +1268,7 @@ SYM(__ld_r13_to_r14_ret): + #endif + + #ifdef L_muldf3 +-#if defined (__ARC700__) || defined (__HS__) ++#ifdef __ARC_MPY__ + #include "ieee-754/muldf3.S" + #elif defined (__ARC_NORM__) && defined(__ARC_MUL64__) + #include "ieee-754/arc600-mul64/muldf3.S" +@@ -1281,7 +1284,7 @@ SYM(__ld_r13_to_r14_ret): + #endif + + #ifdef L_mulsf3 +-#if defined (__ARC700__) || defined (__HS__) ++#ifdef __ARC_MPY__ + #include "ieee-754/mulsf3.S" + #elif defined (__ARC_NORM__) && defined(__ARC_MUL64__) + #include "ieee-754/arc600-mul64/mulsf3.S" +@@ -1293,7 +1296,7 @@ SYM(__ld_r13_to_r14_ret): + #endif + + #ifdef L_divdf3 +-#if defined (__ARC700__) || defined (__HS__) ++#ifdef __ARC_MPY__ + #include "ieee-754/divdf3.S" + #elif defined (__ARC_NORM__) && defined(__ARC_MUL64__) + #include "ieee-754/arc600-mul64/divdf3.S" +@@ -1303,7 +1306,7 @@ SYM(__ld_r13_to_r14_ret): + #endif + + #ifdef L_divsf3 +-#if defined (__ARC700__) || defined (__HS__) ++#ifdef __ARC_MPY__ + #include "ieee-754/divsf3-stdmul.S" + #elif defined (__ARC_NORM__) && defined(__ARC_MUL64__) + #include "ieee-754/arc600-mul64/divsf3.S" +@@ -1421,3 +1424,4 @@ SYM(__ld_r13_to_r14_ret): + #include "ieee-754/ordsf2.S" + #endif + #endif ++#endif /* ARC_OPTFPE */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0027-ARC-libgcc-Fix-defines.patch b/toolchain/gcc/patches/6.3.0/0027-ARC-libgcc-Fix-defines.patch new file mode 100644 index 0000000..b4a4902 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0027-ARC-libgcc-Fix-defines.patch @@ -0,0 +1,198 @@ +From 098f1cb27b914e0e1522e100ff662fc99691da28 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 26 May 2016 12:51:46 +0200 +Subject: [PATCH 27/89] [ARC] [libgcc] Fix defines + +libgcc/ +2016-05-26 Claudiu Zissulescu + + * config/arc/lib1funcs.S (__mulsi3): Use feature defines instead + of checking for cpus. + (__umulsidi3, __umulsi3_highpart, __udivmodsi4, __divsi3) + (__modsi3, __clzsi2): Likewise. +--- + libgcc/config/arc/lib1funcs.S | 45 +++++++++++++++++++++++-------------------- + 1 file changed, 24 insertions(+), 21 deletions(-) + +diff --git a/libgcc/config/arc/lib1funcs.S b/libgcc/config/arc/lib1funcs.S +index 9bb25e0a90ed..422fd956457c 100644 +--- a/libgcc/config/arc/lib1funcs.S ++++ b/libgcc/config/arc/lib1funcs.S +@@ -79,7 +79,7 @@ SYM(__mulsi3): + j_s.d [blink] + mov_s r0,mlo + ENDFUNC(__mulsi3) +-#elif defined (__ARC700__) || defined (__HS__) ++#elif defined (__ARC_MPY__) + HIDDEN_FUNC(__mulsi3) + mpyu r0,r0,r1 + nop_s +@@ -98,7 +98,7 @@ SYM(__mulsi3): + add_s r1,r1,r1 + .Lend: j_s [blink] + ENDFUNC(__mulsi3) +-#elif !defined (__OPTIMIZE_SIZE__) && !defined(__ARC601__) ++#elif !defined (__OPTIMIZE_SIZE__) && defined (__ARC_BARREL_SHIFTER__) + /* Up to 3.5 times faster than the simpler code below, but larger. */ + FUNC(__mulsi3) + ror.f r2,r0,4 +@@ -170,7 +170,8 @@ SYM(__umulsidi3): + umulsi3_highpart implementation; the use of the latter label doesn't + actually benefit ARC601 platforms, but is useful when ARC601 code is linked + against other libraries. */ +-#if defined (__ARC700__) || defined (__ARC_MUL64__) || defined (__ARC601__) ++#if defined (__ARC_MPY__) || defined (__ARC_MUL64__) \ ++ || !defined (__ARC_BARREL_SHIFTER__) + .global SYM(__umulsi3_highpart) + SYM(__umulsi3_highpart): + HIDDEN_FUNC(__umulsi3_highpart) +@@ -188,18 +189,18 @@ SYM(__umulsi3_highpart): + */ + #include "ieee-754/arc-ieee-754.h" + +-#ifdef __ARC700__ ++#ifdef __ARC_MPY__ + mov_s r12,DBL0L + mpyu DBL0L,r12,DBL0H + j_s.d [blink] +- mpyhu DBL0H,r12,DBL0H ++ MPYHU DBL0H,r12,DBL0H + #elif defined (__ARC_MUL64__) + /* Likewise for __ARC_MUL64__ */ + mulu64 r0,r1 + mov_s DBL0L,mlo + j_s.d [blink] + mov_s DBL0H,mhi +-#else /* !__ARC700__ && !__ARC_MUL64__ */ ++#else /* !__ARC_MPY__ && !__ARC_MUL64__ */ + /* Although it might look tempting to extend this to handle muldi3, + using mulsi3 twice with 2.25 cycles per 32 bit add is faster + than one loop with 3 or four cycles per 32 bit add. */ +@@ -223,9 +224,10 @@ SYM(__umulsi3_highpart): + mov_s DBL0L,r3 + j_s.d [blink] + mov DBL0H,r2 +-#endif /* !__ARC700__*/ ++#endif /* !__ARC_MPY__*/ + ENDFUNC(__umulsidi3) +-#if defined (__ARC700__) || defined (__ARC_MUL64__) || defined (__ARC601__) ++#if defined (__ARC_MPY__) || defined (__ARC_MUL64__) \ ++ || !defined (__ARC_BARREL_SHIFTER__) + ENDFUNC(__umulsi3_highpart) + #endif + #endif /* L_umulsidi3 */ +@@ -235,7 +237,8 @@ SYM(__umulsi3_highpart): + /* For use without a barrel shifter, and for ARC700 / ARC_MUL64, the + mulsidi3 algorithms above look better, so for these, there is an + extra label up there. */ +-#if !defined (__ARC700__) && !defined (__ARC_MUL64__) && !defined (__ARC601__) ++#if !defined (__ARC_MPY__) && !defined (__ARC_MUL64__) \ ++ && defined (__ARC_BARREL_SHIFTER__) + .global SYM(__umulsi3_highpart) + SYM(__umulsi3_highpart): + HIDDEN_FUNC(__umulsi3_highpart) +@@ -251,7 +254,7 @@ SYM(__umulsi3_highpart): + /* Make the result register peephole-compatible with mulsidi3. */ + lsr DBL0H,r2,r3 + ENDFUNC(__umulsi3_highpart) +-#endif /* !__ARC700__ && !__ARC601__ */ ++#endif /* !__ARC_MPY__ && __ARC_BARREL_SHIFTER__ */ + #endif /* L_umulsi3_highpart */ + + #ifdef L_divmod_tools +@@ -295,7 +298,7 @@ udivmodsi4(int modwanted, unsigned long num, unsigned long den) + FUNC(__udivmodsi4) + SYM(__udivmodsi4): + +-#if defined (__ARC700__) ++#if defined (__ARC_EA__) + /* Normalize divisor and divident, and then use the appropriate number of + divaw (the number of result bits, or one more) to produce the result. + There are some special conditions that need to be tested: +@@ -368,7 +371,7 @@ SYM(__udivmodsi4): + j_s.d [blink] + mov.c r0,0 + #elif !defined (__OPTIMIZE_SIZE__) +-#ifdef __ARC_NORM__ ++#if defined (__ARC_NORM__) && defined (__ARC_BARREL_SHIFTER__) + lsr_s r2,r0 + brhs.d r1,r2,.Lret0_3 + norm r2,r2 +@@ -393,17 +396,17 @@ SYM(__udivmodsi4): + lsr_s r1,r1 + cmp_s r0,r1 + xor.f r2,lp_count,31 +-#if !defined (__EM__) ++#if !defined (__ARCEM__) && !defined (__ARCHS__) + mov_s lp_count,r2 + #else + mov lp_count,r2 + nop_s +-#endif /* !__EM__ */ ++#endif /* !__ARCEM__ && !__ARCHS__ */ + #endif /* !__ARC_NORM__ */ + sub.cc r0,r0,r1 + mov_s r3,3 + sbc r3,r3,0 +-#ifndef __ARC601__ ++#if defined (__ARC_BARREL_SHIFTER__) + asl_s r3,r3,r2 + rsub r1,r1,1 + lpne @.Lloop2_end +@@ -503,7 +506,7 @@ SYM(__udivsi3): + .global SYM(__divsi3) + FUNC(__divsi3) + +-#ifndef __ARC700__ ++#ifndef __ARC_EA__ + SYM(__divsi3): + /* A5 / ARC60? */ + mov r7,blink +@@ -514,7 +517,7 @@ SYM(__divsi3): + tst r6,r6 + j.d [r7] + neg.mi r0,r0 +-#else /* !ifndef __ARC700__ */ ++#else /* !ifndef __ARC_EA__ */ + ;; We can use the abs, norm, divaw and mpy instructions for ARC700 + #define MULDIV + #ifdef MULDIV +@@ -907,7 +910,7 @@ SYM(__umodsi3): + .global SYM (__modsi3) + FUNC(__modsi3) + SYM(__modsi3): +-#ifndef __ARC700__ ++#ifndef __ARC_EA__ + /* A5 / ARC60? */ + mov_s r12,blink + mov_s r6,r0 +@@ -918,7 +921,7 @@ SYM(__modsi3): + neg_s r0,r1 + j_s.d [r12] + mov.pl r0,r1 +-#else /* __ARC700__ */ ++#else /* __ARC_EA__ */ + abs_s r2,r1 + norm.f r4,r0 + neg r5,r2 +@@ -942,7 +945,7 @@ SYM(__modsi3): + cmp_s r12,r2 + j_s.d [blink] + sub.hs r0,r0,r5 +-#endif /* __ARC700__ */ ++#endif /* !__ARC_EA__ */ + ENDFUNC(__modsi3) + + #endif /* L_modsi3 */ +@@ -959,7 +962,7 @@ SYM(__clzsi2): + j_s.d [blink] + add.pl r0,r0,1 + ENDFUNC(__clzsi2) +-#elif defined (__ARC601__) ++#elif !defined (__ARC_BARREL_SHIFTER__) + FUNC(__clzsi2) + mov lp_count,10 + mov_l r1,0 +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0028-ARC-tests-Update-target-specific-tests.patch b/toolchain/gcc/patches/6.3.0/0028-ARC-tests-Update-target-specific-tests.patch new file mode 100644 index 0000000..21c7599 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0028-ARC-tests-Update-target-specific-tests.patch @@ -0,0 +1,1103 @@ +From 854d96b7ed61fda05faeef383390f875c1736d8d Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 26 May 2016 15:06:04 +0200 +Subject: [PATCH 28/89] [ARC] [tests] Update target specific tests. + +gcc/ +[ARC] [tests] Update tests. + +gcc/ +2016-06-27 Claudiu Zissulescu + + * testsuite/gcc.target/arc/abitest.S: New file. + * testsuite/gcc.target/arc/abitest.h: Likewise. + * testsuite/gcc.target/arc/va_args-1.c: Likewise. + * testsuite/gcc.target/arc/va_args-2.c: Likewise. + * testsuite/gcc.target/arc/va_args-3.c: Likewise. + * testsuite/gcc.target/arc/mcrc.c: Deleted. + * testsuite/gcc.target/arc/mdsp-packa.c: Likewise. + * testsuite/gcc.target/arc/mdvbf.c: Likewise. + * testsuite/gcc.target/arc/mmac-24.c: Likewise. + * testsuite/gcc.target/arc/mmac-d16.c: Likewise. + * testsuite/gcc.target/arc/mno-crc.c: Likewise. + * testsuite/gcc.target/arc/mno-dsp-packa.c: Likewise. + * testsuite/gcc.target/arc/mno-dvbf.c: Likewise. + * testsuite/gcc.target/arc/mno-mac-24.c: Likewise. + * testsuite/gcc.target/arc/mno-mac-d16.c: Likewise. + * testsuite/gcc.target/arc/mno-rtsc.c: Likewise. + * testsuite/gcc.target/arc/mno-xy.c: Likewise. + * testsuite/gcc.target/arc/mrtsc.c: Likewise. + * testsuite/gcc.target/arc/arc.exp (check_effective_target_arcem): + New function. + (check_effective_target_arc700): Likewise. + (check_effective_target_arc6xx): Likewise. + (check_effective_target_arcmpy): Likewise. + (check_effective_target_archs): Likewise. + (check_effective_target_clmcpu): Likewise. + (check_effective_target_barrelshifter): Likewise. + * testsuite/gcc.target/arc/barrel-shifter-1.c: Changed. + * testsuite/gcc.target/arc/builtin_simd.c: Test only for ARC700 + cpus. + * testsuite/gcc.target/arc/cmem-1.c: Changed. + * testsuite/gcc.target/arc/cmem-2.c: Likewise. + * testsuite/gcc.target/arc/cmem-3.c: Likewise. + * testsuite/gcc.target/arc/cmem-4.c: Likewise. + * testsuite/gcc.target/arc/cmem-5.c: Likewise. + * testsuite/gcc.target/arc/cmem-6.c: Likewise. + * testsuite/gcc.target/arc/cmem-7.c: Likewise. + * testsuite/gcc.target/arc/interrupt-1.c: Test for RTIE as well. + * testsuite/gcc.target/arc/interrupt-2.c: Skip it for ARCv2 cores. + * testsuite/gcc.target/arc/interrupt-3.c: Match also ARCv2 + warnings. + * testsuite/gcc.target/arc/jump-around-jump.c: Update options. + * testsuite/gcc.target/arc/mARC601.c: Changed. + * testsuite/gcc.target/arc/mcpu-arc600.c: Changed. + * testsuite/gcc.target/arc/mcpu-arc601.c: Changed. + * testsuite/gcc.target/arc/mcpu-arc700.c: Changed. + * testsuite/gcc.target/arc/mdpfp.c: Skip for ARCv2 cores. + * testsuite/gcc.target/arc/movb-1.c: Changed. + * testsuite/gcc.target/arc/movb-2.c: Likewise. + * testsuite/gcc.target/arc/movb-3.c: Likewise. + * testsuite/gcc.target/arc/movb-4.c: Likewise. + * testsuite/gcc.target/arc/movb-5.c: Likewise. + * testsuite/gcc.target/arc/movb_cl-1.c: Likewise. + * testsuite/gcc.target/arc/movb_cl-2.c: Likewise. + * testsuite/gcc.target/arc/movbi_cl-1.c: Likewise. + * testsuite/gcc.target/arc/movh_cl-1.c: Likewise. + * testsuite/gcc.target/arc/mspfp.c: Skip for ARC HS cores. + * testsuite/gcc.target/arc/mul64.c: Enable it only for ARC600. + * testsuite/gcc.target/arc/mulsi3_highpart-1.c: Scan for ARCv2 + instructions. + * testsuite/gcc.target/arc/mulsi3_highpart-2.c: Skip it for ARCv1 + cores. + * testsuite/gcc.target/arc/no-dpfp-lrsr.c: Skip it for ARC HS. + * testsuite/gcc.target/arc/trsub.c: Only for ARC EM cores. + * testsuite/gcc.target/arc/builtin_simdarc.c: Changed. + * testsuite/gcc.target/arc/extzv-1.c: Likewise. + * testsuite/gcc.target/arc/insv-1.c: Likewise. + * testsuite/gcc.target/arc/insv-2.c: Likewise. + * testsuite/gcc.target/arc/mA6.c: Likewise. + * testsuite/gcc.target/arc/mA7.c: Likewise. + * testsuite/gcc.target/arc/mARC600.c: Likewise. + * testsuite/gcc.target/arc/mARC700.c: Likewise. + * testsuite/gcc.target/arc/mcpu-arc600.c: Likewise. + * testsuite/gcc.target/arc/mcpu-arc700.c: Likewise. + * testsuite/gcc.target/arc/movl-1.c: Likewise. + * testsuite/gcc.target/arc/nps400-1.c: Likewise. + * testsuite/gcc.target/arc/trsub.c: Likewise. + * testsuite/gcc.target/arc/barrel-shifter-2.c: Check for barrel + shifter configuration. + * testsuite/gcc.target/arc/mlock.c: Skip for arc6xx + configurations. + * testsuite/gcc.target/arc/mswape.c: Likewise. +--- + gcc/testsuite/gcc.target/arc/abitest.S | 31 ++++++++++ + gcc/testsuite/gcc.target/arc/abitest.h | 17 ++++++ + gcc/testsuite/gcc.target/arc/arc.exp | 74 +++++++++++++++++++++++- + gcc/testsuite/gcc.target/arc/barrel-shifter-1.c | 2 +- + gcc/testsuite/gcc.target/arc/barrel-shifter-2.c | 1 + + gcc/testsuite/gcc.target/arc/builtin_simd.c | 1 + + gcc/testsuite/gcc.target/arc/builtin_simdarc.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-1.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-2.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-3.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-4.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-5.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-6.c | 1 + + gcc/testsuite/gcc.target/arc/cmem-7.c | 1 + + gcc/testsuite/gcc.target/arc/extzv-1.c | 1 + + gcc/testsuite/gcc.target/arc/insv-1.c | 1 + + gcc/testsuite/gcc.target/arc/insv-2.c | 1 + + gcc/testsuite/gcc.target/arc/interrupt-1.c | 7 ++- + gcc/testsuite/gcc.target/arc/interrupt-2.c | 1 + + gcc/testsuite/gcc.target/arc/interrupt-3.c | 2 +- + gcc/testsuite/gcc.target/arc/jump-around-jump.c | 2 +- + gcc/testsuite/gcc.target/arc/mA6.c | 1 + + gcc/testsuite/gcc.target/arc/mA7.c | 1 + + gcc/testsuite/gcc.target/arc/mARC600.c | 1 + + gcc/testsuite/gcc.target/arc/mARC601.c | 3 +- + gcc/testsuite/gcc.target/arc/mARC700.c | 1 + + gcc/testsuite/gcc.target/arc/mcpu-arc600.c | 3 +- + gcc/testsuite/gcc.target/arc/mcpu-arc601.c | 5 +- + gcc/testsuite/gcc.target/arc/mcpu-arc700.c | 3 +- + gcc/testsuite/gcc.target/arc/mcrc.c | 9 --- + gcc/testsuite/gcc.target/arc/mdpfp.c | 1 + + gcc/testsuite/gcc.target/arc/mdsp-packa.c | 9 --- + gcc/testsuite/gcc.target/arc/mdvbf.c | 9 --- + gcc/testsuite/gcc.target/arc/mlock.c | 1 + + gcc/testsuite/gcc.target/arc/mmac-24.c | 9 --- + gcc/testsuite/gcc.target/arc/mmac-d16.c | 9 --- + gcc/testsuite/gcc.target/arc/mno-crc.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-dsp-packa.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-dvbf.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-mac-24.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-mac-d16.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-rtsc.c | 11 ---- + gcc/testsuite/gcc.target/arc/mno-xy.c | 10 ---- + gcc/testsuite/gcc.target/arc/movb-1.c | 1 + + gcc/testsuite/gcc.target/arc/movb-2.c | 1 + + gcc/testsuite/gcc.target/arc/movb-3.c | 1 + + gcc/testsuite/gcc.target/arc/movb-4.c | 1 + + gcc/testsuite/gcc.target/arc/movb-5.c | 1 + + gcc/testsuite/gcc.target/arc/movb_cl-1.c | 1 + + gcc/testsuite/gcc.target/arc/movb_cl-2.c | 1 + + gcc/testsuite/gcc.target/arc/movbi_cl-1.c | 1 + + gcc/testsuite/gcc.target/arc/movh_cl-1.c | 1 + + gcc/testsuite/gcc.target/arc/movl-1.c | 1 + + gcc/testsuite/gcc.target/arc/mrtsc.c | 9 --- + gcc/testsuite/gcc.target/arc/mspfp.c | 1 + + gcc/testsuite/gcc.target/arc/mswape.c | 1 + + gcc/testsuite/gcc.target/arc/mul64.c | 4 +- + gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c | 5 +- + gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c | 4 +- + gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c | 1 + + gcc/testsuite/gcc.target/arc/nps400-1.c | 1 + + gcc/testsuite/gcc.target/arc/trsub.c | 1 + + gcc/testsuite/gcc.target/arc/va_args-1.c | 16 +++++ + gcc/testsuite/gcc.target/arc/va_args-2.c | 14 +++++ + gcc/testsuite/gcc.target/arc/va_args-3.c | 15 +++++ + 65 files changed, 227 insertions(+), 145 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/abitest.S + create mode 100644 gcc/testsuite/gcc.target/arc/abitest.h + delete mode 100644 gcc/testsuite/gcc.target/arc/mcrc.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mdsp-packa.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mdvbf.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-24.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mmac-d16.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-crc.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dsp-packa.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-dvbf.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-24.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-mac-d16.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-rtsc.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mno-xy.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mrtsc.c + create mode 100644 gcc/testsuite/gcc.target/arc/va_args-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/va_args-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/va_args-3.c + +diff --git a/gcc/testsuite/gcc.target/arc/abitest.S b/gcc/testsuite/gcc.target/arc/abitest.S +new file mode 100644 +index 000000000000..7be935b10346 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/abitest.S +@@ -0,0 +1,31 @@ ++/* { dg-do assemble } */ ++#ifndef ENTRY ++#define ENTRY(nm) \ ++ .text ` \ ++ .align 4 ` \ ++ .globl nm ` \ ++ .type nm,@function ` \ ++nm: ++#endif ++ ++#ifndef END ++#define END(name) .size name,.-name ++#endif ++ ++ENTRY(tsyscall) ++ENTRY(clone) ++ add r0,r0,r1 ++ add r0,r0,r2 ++ add r0,r0,r3 ++ add r0,r0,r4 ++ add r0,r0,r5 ++ j_s.d [blink] ++ add r0,r0,r6 ++END(tsyscall) ++END(clone) ++ ++ENTRY(abidi) ++ add.f r0,r1,1 ++ j_s.d [blink] ++ adc r1,r2,0 ++END(abidi) +diff --git a/gcc/testsuite/gcc.target/arc/abitest.h b/gcc/testsuite/gcc.target/arc/abitest.h +new file mode 100644 +index 000000000000..26de3e4f7e42 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/abitest.h +@@ -0,0 +1,17 @@ ++#ifndef _DG_ABITEST_H ++#define _DG_ABITEST_H 1 ++ ++#ifdef __ASSEMBLER__ ++ ++#define ENTRY(nm) \ ++ .text ` \ ++ .align 4 ` \ ++ .globl nm ` \ ++ .type nm,@function ` \ ++nm: ++ ++#define END(name) .size name,.-name ++ ++#endif /* __ASSEMBLER __*/ ++ ++#endif /*_DG_ABITEST_H*/ +diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp +index fae2ece7f6f3..62583cd0321e 100644 +--- a/gcc/testsuite/gcc.target/arc/arc.exp ++++ b/gcc/testsuite/gcc.target/arc/arc.exp +@@ -4,12 +4,12 @@ + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 3 of the License, 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 GCC; see the file COPYING3. If not see + # . +@@ -24,6 +24,76 @@ if ![istarget arc*-*-*] then { + # Load support procs. + load_lib gcc-dg.exp + ++# Return 1 if this is a compiler supporting ARCv2 EM as default processor ++proc check_effective_target_arcem { } { ++ return [check_no_compiler_messages arcem assembly { ++ #if !defined(__ARCEM__) ++ #error No ARC EM ++ #endif ++ }] ++} ++ ++# Return 1 if we compile for ARC700 ++proc check_effective_target_arc700 { } { ++ return [check_no_compiler_messages arc700 assembly { ++ #if !defined(__ARC700__) ++ #error No ARC 700 ++ #endif ++ }] ++} ++ ++# Return 1 if we compile for ARC6xx ++proc check_effective_target_arc6xx { } { ++ return [check_no_compiler_messages arc6xx assembly { ++ #if !defined(__ARC600__) && !defined(__ARC601__) ++ #error No ARC 6xx ++ #endif ++ }] ++} ++ ++# Return 1 if we have mpy ++proc check_effective_target_arcmpy { } { ++ return [check_no_compiler_messages arcmpy assembly { ++ #if !defined(__ARC_MPY__) ++ #error No MPY ++ #endif ++ }] ++} ++ ++# Return 1 if this is a compiler supporting ARC HS as default processor ++proc check_effective_target_archs { } { ++ return [check_no_compiler_messages archs assembly { ++ #if !defined(__ARCHS__) ++ #error No ARC HS ++ #endif ++ }] ++} ++ ++proc check_cl { flags } { ++ return [check_no_compiler_messages check_$flags assembly { ++ #if !defined(__arc__) ++ #error Extra mcpu options ++ #endif ++ } "$flags"] ++} ++ ++# Return 1 if there are no extra mcpu options given via command line ++proc check_effective_target_clmcpu { } { ++ if { [check_cl "-mcpu=arc700"] ++ && [check_cl "-mcpu=arcem" ] } { ++ return 1 ++ } ++ return 0 ++} ++ ++proc check_effective_target_barrelshifter { } { ++ return [check_no_compiler_messages barrelshifter assembly { ++ #if !defined(__ARC_BARREL_SHIFTER__) ++ #error No barrel shifter for this confi ++ #endif ++ }] ++} ++ + # If a testcase doesn't have special options, use these. + global DEFAULT_CFLAGS + if ![info exists DEFAULT_CFLAGS] then { +diff --git a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c +index a0eb6d70c39e..5cfb282f6ac7 100644 +--- a/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c ++++ b/gcc/testsuite/gcc.target/arc/barrel-shifter-1.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mcpu=ARC601 -mbarrel-shifter" } */ ++/* { dg-options "-O2 -mbarrel-shifter" } */ + int i; + + int f (void) +diff --git a/gcc/testsuite/gcc.target/arc/barrel-shifter-2.c b/gcc/testsuite/gcc.target/arc/barrel-shifter-2.c +index 97998fbf1a38..8e0bb9a8a60b 100644 +--- a/gcc/testsuite/gcc.target/arc/barrel-shifter-2.c ++++ b/gcc/testsuite/gcc.target/arc/barrel-shifter-2.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { barrelshifter } } } */ + int i; + + int f (void) +diff --git a/gcc/testsuite/gcc.target/arc/builtin_simd.c b/gcc/testsuite/gcc.target/arc/builtin_simd.c +index fff27a479607..6b0252186c69 100644 +--- a/gcc/testsuite/gcc.target/arc/builtin_simd.c ++++ b/gcc/testsuite/gcc.target/arc/builtin_simd.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-O2 -Werror-implicit-function-declaration -mARC700 -msimd" } */ + + #define STEST1(name, rettype, op1) \ +diff --git a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c +index 68aae40ca58e..0cfe2ad767d4 100644 +--- a/gcc/testsuite/gcc.target/arc/builtin_simdarc.c ++++ b/gcc/testsuite/gcc.target/arc/builtin_simdarc.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=archs -O2 -Werror-implicit-function-declaration -mmpy-option=9" } */ + + #define STEST(name, rettype, op1type, op2type) \ +diff --git a/gcc/testsuite/gcc.target/arc/cmem-1.c b/gcc/testsuite/gcc.target/arc/cmem-1.c +index 7f36afbfa7d8..8ed5dcf2f019 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-1.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-2.c b/gcc/testsuite/gcc.target/arc/cmem-2.c +index a3d7c130b5e8..39bfb2885c78 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-2.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-2.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-3.c b/gcc/testsuite/gcc.target/arc/cmem-3.c +index dee73b5c5d30..109084f01fb3 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-3.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-3.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-4.c b/gcc/testsuite/gcc.target/arc/cmem-4.c +index 1da6bce77c48..4ac8a22f2313 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-4.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-4.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_private"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-5.c b/gcc/testsuite/gcc.target/arc/cmem-5.c +index ad6904f73605..451218b97651 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-5.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-5.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-6.c b/gcc/testsuite/gcc.target/arc/cmem-6.c +index 24bc39bfd07c..0ed06085514b 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-6.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-6.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + #define CMEM_SECTION_ATTR __attribute__ ((section (".cmem_shared"))); +diff --git a/gcc/testsuite/gcc.target/arc/cmem-7.c b/gcc/testsuite/gcc.target/arc/cmem-7.c +index 72ee7bdffafb..026732711728 100644 +--- a/gcc/testsuite/gcc.target/arc/cmem-7.c ++++ b/gcc/testsuite/gcc.target/arc/cmem-7.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mcmem" } */ + + struct some_struct +diff --git a/gcc/testsuite/gcc.target/arc/extzv-1.c b/gcc/testsuite/gcc.target/arc/extzv-1.c +index 242f522f187e..1e5533a72bb7 100644 +--- a/gcc/testsuite/gcc.target/arc/extzv-1.c ++++ b/gcc/testsuite/gcc.target/arc/extzv-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct foo { unsigned a: 3, b: 5, c: 24; }; +diff --git a/gcc/testsuite/gcc.target/arc/insv-1.c b/gcc/testsuite/gcc.target/arc/insv-1.c +index 75d47e9b1b3f..29e4188a2e2b 100644 +--- a/gcc/testsuite/gcc.target/arc/insv-1.c ++++ b/gcc/testsuite/gcc.target/arc/insv-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + /* ??? Irrespective of insn set, generated code for this is a mess. */ +diff --git a/gcc/testsuite/gcc.target/arc/insv-2.c b/gcc/testsuite/gcc.target/arc/insv-2.c +index 16525511698c..620acecc2e2f 100644 +--- a/gcc/testsuite/gcc.target/arc/insv-2.c ++++ b/gcc/testsuite/gcc.target/arc/insv-2.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct foo { unsigned a: 3, b: 8, c: 21; } bar; +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c +index 70514572ea56..8a2002bf1c0f 100644 +--- a/gcc/testsuite/gcc.target/arc/interrupt-1.c ++++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c +@@ -1,5 +1,10 @@ ++#if defined (__ARCHS__) || defined (__ARCEM__) ++void __attribute__ ((interrupt("ilink"))) ++#else + void __attribute__ ((interrupt("ilink1"))) ++#endif + handler1 (void) + { + } +-/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */ ++/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc700 || arc6xx } } } } */ ++/* { dg-final { scan-assembler-times "rtie" 1 { target { arcem || archs } } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c b/gcc/testsuite/gcc.target/arc/interrupt-2.c +index ee8593b30391..285ebd57a220 100644 +--- a/gcc/testsuite/gcc.target/arc/interrupt-2.c ++++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c +@@ -1,3 +1,4 @@ ++/* { dg-skip-if "ilink2 is not an ARCv2 register" { archs || arcem } } */ + void __attribute__ ((interrupt("ilink2"))) + handler1 (void) + { +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c b/gcc/testsuite/gcc.target/arc/interrupt-3.c +index fa598d67e6b1..b0cad88de95e 100644 +--- a/gcc/testsuite/gcc.target/arc/interrupt-3.c ++++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c +@@ -5,7 +5,7 @@ handler0 (void) + + void __attribute__ ((interrupt("you load too"))) + handler1 (void) +-{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */ ++{ /* { dg-warning "is not \"ilink" } */ + } + + void __attribute__ ((interrupt(42))) +diff --git a/gcc/testsuite/gcc.target/arc/jump-around-jump.c b/gcc/testsuite/gcc.target/arc/jump-around-jump.c +index 338c66752385..2fd3fb644c16 100644 +--- a/gcc/testsuite/gcc.target/arc/jump-around-jump.c ++++ b/gcc/testsuite/gcc.target/arc/jump-around-jump.c +@@ -1,5 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-Os -mlock -mswape -mrtsc -fno-reorder-blocks" } */ ++/* { dg-options "-Os -mlock -mswape -fno-reorder-blocks" } */ + + /* This caused an ICE in arc_ifcvt when the 1->3 state change was not + implemented for TYPE_UNCOND_BRANCH in arc_ccfsm_post_advance. */ +diff --git a/gcc/testsuite/gcc.target/arc/mA6.c b/gcc/testsuite/gcc.target/arc/mA6.c +index 2e15a86f8a4d..c4eeb6feadcb 100644 +--- a/gcc/testsuite/gcc.target/arc/mA6.c ++++ b/gcc/testsuite/gcc.target/arc/mA6.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mA6" } */ + + /* { dg-final { scan-assembler ".cpu ARC600" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mA7.c b/gcc/testsuite/gcc.target/arc/mA7.c +index c4430f43b416..a3c6f8204afb 100644 +--- a/gcc/testsuite/gcc.target/arc/mA7.c ++++ b/gcc/testsuite/gcc.target/arc/mA7.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mA7" } */ + + /* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mARC600.c b/gcc/testsuite/gcc.target/arc/mARC600.c +index 20e086aa754f..6a80457b1945 100644 +--- a/gcc/testsuite/gcc.target/arc/mARC600.c ++++ b/gcc/testsuite/gcc.target/arc/mARC600.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mARC600" } */ + + /* { dg-final { scan-assembler ".cpu ARC600" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mARC601.c b/gcc/testsuite/gcc.target/arc/mARC601.c +index 1d30da4cafb1..d2386613eb08 100644 +--- a/gcc/testsuite/gcc.target/arc/mARC601.c ++++ b/gcc/testsuite/gcc.target/arc/mARC601.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mARC601" } */ + +-/* { dg-final { scan-assembler ".cpu ARC601" } } */ ++/* { dg-final { scan-assembler ".cpu ARC60.*" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mARC700.c b/gcc/testsuite/gcc.target/arc/mARC700.c +index 43e9baa3f301..d34583f46aa1 100644 +--- a/gcc/testsuite/gcc.target/arc/mARC700.c ++++ b/gcc/testsuite/gcc.target/arc/mARC700.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mARC700" } */ + + /* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c +index 4c915fda0e38..bd1dc9599a6d 100644 +--- a/gcc/testsuite/gcc.target/arc/mcpu-arc600.c ++++ b/gcc/testsuite/gcc.target/arc/mcpu-arc600.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-mcpu=ARC600" } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ ++/* { dg-options "-mcpu=arc600" } */ + + /* { dg-final { scan-assembler ".cpu ARC600" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c +index 7c93c9dc4acf..8ef046efb867 100644 +--- a/gcc/testsuite/gcc.target/arc/mcpu-arc601.c ++++ b/gcc/testsuite/gcc.target/arc/mcpu-arc601.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-mcpu=ARC601" } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ ++/* { dg-options "-mcpu=arc601" } */ + +-/* { dg-final { scan-assembler ".cpu ARC601" } } */ ++/* { dg-final { scan-assembler ".cpu ARC60.*" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c +index c805a5af76b1..25bb40029864 100644 +--- a/gcc/testsuite/gcc.target/arc/mcpu-arc700.c ++++ b/gcc/testsuite/gcc.target/arc/mcpu-arc700.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ +-/* { dg-options "-mcpu=ARC700" } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ ++/* { dg-options "-mcpu=arc700" } */ + + /* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mcrc.c b/gcc/testsuite/gcc.target/arc/mcrc.c +deleted file mode 100644 +index d3780bb00d6b..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mcrc.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mcrc" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mdpfp.c b/gcc/testsuite/gcc.target/arc/mdpfp.c +index 4bbc9057b856..aa6bdfa1c51f 100644 +--- a/gcc/testsuite/gcc.target/arc/mdpfp.c ++++ b/gcc/testsuite/gcc.target/arc/mdpfp.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */ + /* { dg-options "-O2 -mdpfp" } */ + + double i; +diff --git a/gcc/testsuite/gcc.target/arc/mdsp-packa.c b/gcc/testsuite/gcc.target/arc/mdsp-packa.c +deleted file mode 100644 +index f013a6dd1ea6..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mdsp-packa.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mdsp-packa" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mdvbf.c b/gcc/testsuite/gcc.target/arc/mdvbf.c +deleted file mode 100644 +index e2e545e8bb32..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mdvbf.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mdvbf" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mlock.c b/gcc/testsuite/gcc.target/arc/mlock.c +index 3a8b050c30ef..4b2d9e01f07f 100644 +--- a/gcc/testsuite/gcc.target/arc/mlock.c ++++ b/gcc/testsuite/gcc.target/arc/mlock.c +@@ -1,6 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-mlock" } */ + /* { dg-do assemble } */ ++/* { dg-skip-if "" { arc6xx } } */ + + int f (void *p) + { +diff --git a/gcc/testsuite/gcc.target/arc/mmac-24.c b/gcc/testsuite/gcc.target/arc/mmac-24.c +deleted file mode 100644 +index 30cb6981a03f..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mmac-24.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mmac-24" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mmac-d16.c b/gcc/testsuite/gcc.target/arc/mmac-d16.c +deleted file mode 100644 +index 0570011fd267..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mmac-d16.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mmac-d16" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-crc.c b/gcc/testsuite/gcc.target/arc/mno-crc.c +deleted file mode 100644 +index 70ab9c117614..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-crc.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-crc" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("crc %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c b/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c +deleted file mode 100644 +index eb21522af063..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-dsp-packa.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-dsp-packa" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("minidl %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-dvbf.c b/gcc/testsuite/gcc.target/arc/mno-dvbf.c +deleted file mode 100644 +index ea96d987c186..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-dvbf.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-dvbf" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("vbfdw %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-24.c b/gcc/testsuite/gcc.target/arc/mno-mac-24.c +deleted file mode 100644 +index b4839579b125..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-mac-24.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-mac-24" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("mult %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c b/gcc/testsuite/gcc.target/arc/mno-mac-d16.c +deleted file mode 100644 +index 68a20f4f55ac..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-mac-d16.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-mac-d16" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("muldw %1, %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-rtsc.c b/gcc/testsuite/gcc.target/arc/mno-rtsc.c +deleted file mode 100644 +index d74a60e93514..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-rtsc.c ++++ /dev/null +@@ -1,11 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-rtsc" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-int f (int i) +-{ +- __asm__("rtsc %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mno-xy.c b/gcc/testsuite/gcc.target/arc/mno-xy.c +deleted file mode 100644 +index e378b3fc9b63..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mno-xy.c ++++ /dev/null +@@ -1,10 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mno-xy" } */ +-/* Would also like to assemble and check that we get the expected +- "Error: bad instruction" assembler messages, but at the moment our +- testharness can't do that. */ +- +-void f (int i) +-{ +- __asm__("add x0_u0, x0_u0, %0" : : "r" (i)); +-} +diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c +index 65d4ba4b6ab4..965fd66aa99c 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-1.c ++++ b/gcc/testsuite/gcc.target/arc/movb-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct { unsigned a: 5, b: 8, c: 19; } foo; +diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c +index 1ba9976a566d..9bd6d4187fd3 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-2.c ++++ b/gcc/testsuite/gcc.target/arc/movb-2.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct { unsigned a: 23, b: 9; } foo; +diff --git a/gcc/testsuite/gcc.target/arc/movb-3.c b/gcc/testsuite/gcc.target/arc/movb-3.c +index 0895154abb67..34145d6cc6f2 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-3.c ++++ b/gcc/testsuite/gcc.target/arc/movb-3.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct { int a: 23, b: 9; } foo; +diff --git a/gcc/testsuite/gcc.target/arc/movb-4.c b/gcc/testsuite/gcc.target/arc/movb-4.c +index 89bf2c2b1232..83efad647d8d 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-4.c ++++ b/gcc/testsuite/gcc.target/arc/movb-4.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct { int a: 13, b: 19; } foo; +diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c +index 9dbe8a1e09a8..0bcdd1c7874c 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-5.c ++++ b/gcc/testsuite/gcc.target/arc/movb-5.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct { int a: 23, b: 9; } foo; +diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-1.c b/gcc/testsuite/gcc.target/arc/movb_cl-1.c +index 402250ce5302..977a0c2fbf02 100644 +--- a/gcc/testsuite/gcc.target/arc/movb_cl-1.c ++++ b/gcc/testsuite/gcc.target/arc/movb_cl-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + int +diff --git a/gcc/testsuite/gcc.target/arc/movb_cl-2.c b/gcc/testsuite/gcc.target/arc/movb_cl-2.c +index d2e5a944a6ea..4a1484a3e4c7 100644 +--- a/gcc/testsuite/gcc.target/arc/movb_cl-2.c ++++ b/gcc/testsuite/gcc.target/arc/movb_cl-2.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + extern void g (void); +diff --git a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c +index 3c457dbe5287..a86d06f30b4e 100644 +--- a/gcc/testsuite/gcc.target/arc/movbi_cl-1.c ++++ b/gcc/testsuite/gcc.target/arc/movbi_cl-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + int +diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +index 220cd9d72b94..13c0f3434433 100644 +--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c ++++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + struct thing +diff --git a/gcc/testsuite/gcc.target/arc/movl-1.c b/gcc/testsuite/gcc.target/arc/movl-1.c +index f1f0130a2b07..c44ca8d2ccde 100644 +--- a/gcc/testsuite/gcc.target/arc/movl-1.c ++++ b/gcc/testsuite/gcc.target/arc/movl-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -O2 -mbitops" } */ + + int +diff --git a/gcc/testsuite/gcc.target/arc/mrtsc.c b/gcc/testsuite/gcc.target/arc/mrtsc.c +deleted file mode 100644 +index 31852a5e479b..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mrtsc.c ++++ /dev/null +@@ -1,9 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mrtsc" } */ +-/* { dg-do assemble } */ +- +-int f (int i) +-{ +- __asm__("rtsc %1, %1" : "=r"(i) : "r"(i)); +- return i; +-} +diff --git a/gcc/testsuite/gcc.target/arc/mspfp.c b/gcc/testsuite/gcc.target/arc/mspfp.c +index 0e41ff89d351..19cb97828fbb 100644 +--- a/gcc/testsuite/gcc.target/arc/mspfp.c ++++ b/gcc/testsuite/gcc.target/arc/mspfp.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "FPX is not an ARC HS extension" { archs } } */ + /* { dg-options "-O2 -mspfp" } */ + + float i; +diff --git a/gcc/testsuite/gcc.target/arc/mswape.c b/gcc/testsuite/gcc.target/arc/mswape.c +index 692e6a2bb6ee..545968f114e2 100644 +--- a/gcc/testsuite/gcc.target/arc/mswape.c ++++ b/gcc/testsuite/gcc.target/arc/mswape.c +@@ -1,6 +1,7 @@ + /* { dg-do compile } */ + /* { dg-options "-mswape" } */ + /* { dg-do assemble } */ ++/* { dg-skip-if "" { arc6xx } } */ + + int f (int i) + { +diff --git a/gcc/testsuite/gcc.target/arc/mul64.c b/gcc/testsuite/gcc.target/arc/mul64.c +index 3678b2799d54..fb8e7750c535 100644 +--- a/gcc/testsuite/gcc.target/arc/mul64.c ++++ b/gcc/testsuite/gcc.target/arc/mul64.c +@@ -1,5 +1,7 @@ + /* { dg-do compile } */ +-/* { dg-options "-O2 -mcpu=ARC600 -mmul64" } */ ++/* { dg-skip-if "MUL64 is ARC600 extension" { ! { arc6xx } } } */ ++/* { dg-options "-O2 -mmul64" } */ ++ + #include + + int64_t i; +diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c +index 398ecfe948ee..57cb95b91fc1 100644 +--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c ++++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c +@@ -1,5 +1,5 @@ + /* { dg-do run } */ +-/* { dg-options "-O2 -mARC700 --save-temps" } */ ++/* { dg-options "-save-temps -O2" } */ + + #include + +@@ -25,4 +25,5 @@ main (void) + return 0; + } + +-/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */ ++/* { dg-final { scan-assembler "mpyhu\[ \t\]" { target { arc700 } } } } */ ++/* { dg-final { scan-assembler "mpy.u\[ \t\]" { target { { ! { arc700 } } && arcmpy } } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c +index ccc74e7b1ada..287d96d4ee9a 100644 +--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c ++++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c +@@ -1,5 +1,7 @@ + /* { dg-do run } */ +-/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */ ++/* { dg-skip-if "ARC700 always has mpy option on" { arc700 } } */ ++/* { dg-skip-if "ARC600 doesn't have mpy instruction" { arc6xx } } */ ++/* { dg-options "-O2 --save-temps -mmpy-option=0" } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c +index e4e23e4a40f6..61f07b53aace 100644 +--- a/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c ++++ b/gcc/testsuite/gcc.target/arc/no-dpfp-lrsr.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "FPX cannot execute on ARC HS" { archs } } */ + /* { dg-options "-O2 -mdpfp -mno-dpfp-lrsr" } */ + + double i; +diff --git a/gcc/testsuite/gcc.target/arc/nps400-1.c b/gcc/testsuite/gcc.target/arc/nps400-1.c +index f3d62718bb07..504aad734ccb 100644 +--- a/gcc/testsuite/gcc.target/arc/nps400-1.c ++++ b/gcc/testsuite/gcc.target/arc/nps400-1.c +@@ -1,4 +1,5 @@ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mcpu=nps400 -mq-class -mbitops -munaligned-access -mcmem -O2 -fno-strict-aliasing" } */ + + enum npsdp_mem_space_type { +diff --git a/gcc/testsuite/gcc.target/arc/trsub.c b/gcc/testsuite/gcc.target/arc/trsub.c +index 031935fdc8f5..8ea5711c6ee4 100644 +--- a/gcc/testsuite/gcc.target/arc/trsub.c ++++ b/gcc/testsuite/gcc.target/arc/trsub.c +@@ -1,6 +1,7 @@ + /* Tests if we generate rsub instructions when compiling using + floating point assist instructions. */ + /* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ + /* { dg-options "-mfpu=fpuda -mcpu=arcem" } */ + + double foo (double a) +diff --git a/gcc/testsuite/gcc.target/arc/va_args-1.c b/gcc/testsuite/gcc.target/arc/va_args-1.c +new file mode 100644 +index 000000000000..4a35d122ade4 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/va_args-1.c +@@ -0,0 +1,16 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++/* { dg-additional-sources "abitest.S" } */ ++ ++extern long tsyscall (long int sysnum, ...); ++ ++int main (void) ++{ ++ long a; ++ ++ a = tsyscall (1, 2, 3, 4, 5, 6, 7); ++ ++ if (a != 28) ++ return 1; ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/arc/va_args-2.c b/gcc/testsuite/gcc.target/arc/va_args-2.c +new file mode 100644 +index 000000000000..18f48b030b04 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/va_args-2.c +@@ -0,0 +1,14 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++/* { dg-additional-sources "abitest.S" } */ ++ ++extern int clone(int (*fn)(void *), void *child_stack, ++ int flags, void *arg, ...); ++ ++int main (void) ++{ ++ int a = clone ((void *) 1, (void *)2, 3, (void *) 4, 5, 6, 7); ++ if (a != 28) ++ return 1; ++ return 0; ++} +diff --git a/gcc/testsuite/gcc.target/arc/va_args-3.c b/gcc/testsuite/gcc.target/arc/va_args-3.c +new file mode 100644 +index 000000000000..45624c153c67 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/va_args-3.c +@@ -0,0 +1,15 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++/* { dg-additional-sources "abitest.S" } */ ++ ++extern long long abidi (int a, ...); ++ ++int main (void) ++{ ++ long long a = 1; ++ a = abidi (10, a); ++ ++ if (a != 2) ++ return 1; ++ return 0; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0029-ARC-Various-fixes.patch b/toolchain/gcc/patches/6.3.0/0029-ARC-Various-fixes.patch new file mode 100644 index 0000000..c0d8c5a --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0029-ARC-Various-fixes.patch @@ -0,0 +1,84 @@ +From 955d2b920d3557f505179c11a61d10b7b9ff4f93 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 7 Jun 2016 11:01:48 +0200 +Subject: [PATCH 29/89] [ARC] Various fixes. + +The ifconversion was failing because a move involving the lp_count was +not match by movsi_ne. This patch updates the constraints such that +movsi_ne will match. The failing test is dg-torture.exp=pr68955.c for +archs and without small data. + +gcc/ +2016-07-11 Claudiu Zissulescu + + * config/arc/arc.h (REG_CLASS_NAMES): Reorder. + * config/arc/arc.md (*add_n): Change. + (*sub_n): Likewise. + (movsi_ne): Update constraint to Rac. +--- + gcc/config/arc/arc.h | 2 +- + gcc/config/arc/arc.md | 18 +++++++++--------- + 2 files changed, 10 insertions(+), 10 deletions(-) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 795831d2c810..365062ede280 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -619,10 +619,10 @@ enum reg_class + "MPY_WRITABLE_CORE_REGS", \ + "WRITABLE_CORE_REGS", \ + "CHEAP_CORE_REGS", \ ++ "ALL_CORE_REGS", \ + "R0R3_CD_REGS", \ + "R0R1_CD_REGS", \ + "AC16_H_REGS", \ +- "ALL_CORE_REGS", \ + "ALL_REGS" \ + } + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 87e6a172a9a5..375f2b7fa2bc 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -2901,10 +2901,10 @@ + (set (match_dup 3) (match_dup 4))]) + + (define_insn "*add_n" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W,W,w,w") +- (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq,c,c,c,c,c") +- (match_operand:SI 2 "_2_4_8_operand" "")) +- (match_operand:SI 3 "nonmemory_operand" "0,0,c,?Cal,?c,??Cal")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,W, W,w,w") ++ (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "Rcqq, c,c, c,w,w") ++ (match_operand:SI 2 "_2_4_8_operand" "")) ++ (match_operand:SI 3 "nonmemory_operand" "0, 0,c,?Cal,c,Cal")))] + "" + "add%z2%? %0,%3,%1%&" + [(set_attr "type" "shift") +@@ -2916,9 +2916,9 @@ + ;; N.B. sub[123] has the operands of the MINUS in the opposite order from + ;; what synth_mult likes. + (define_insn "*sub_n" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") +- (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") +- (mult:SI (match_operand:SI 2 "register_operand" "c,c,c") ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") ++ (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") ++ (mult:SI (match_operand:SI 2 "register_operand" "w,w,w") + (match_operand:SI 3 "_2_4_8_operand" ""))))] + "" + "sub%z3%? %0,%1,%2" +@@ -3574,8 +3574,8 @@ + (define_insn "*movsi_ne" + [(cond_exec + (ne (match_operand:CC_Z 2 "cc_use_register" "Rcc, Rcc, Rcc,Rcc,Rcc") (const_int 0)) +- (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w") +- (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal, Lc,?Cal")))] ++ (set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq#q,Rcq#q, w,w") ++ (match_operand:SI 1 "nonmemory_operand" "C_0, h, ?Cal,LRac,?Cal")))] + "" + "@ + * current_insn_predicate = 0; return \"sub%?.ne %0,%0,%0%&\"; +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0030-ARC-Add-simple-shift-rotate-ops.patch b/toolchain/gcc/patches/6.3.0/0030-ARC-Add-simple-shift-rotate-ops.patch new file mode 100644 index 0000000..175ecf0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0030-ARC-Add-simple-shift-rotate-ops.patch @@ -0,0 +1,68 @@ +From c17c97bccaec0db96c468c575bbc769d1478a756 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 9 Jun 2016 13:26:21 +0200 +Subject: [PATCH 30/89] [ARC] Add simple shift/rotate ops. + +gcc/ +2016-06-09 Claudiu Zissulescu + + * config/arc/arc.md (*rotrsi3_cnt1): New pattern, + (*ashlsi2_cnt1, *lshrsi3_cnt1, *ashrsi3_cnt1): Likewise. +--- + gcc/config/arc/arc.md | 40 ++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 40 insertions(+) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 375f2b7fa2bc..64afb8bf7bf6 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -6219,6 +6219,46 @@ + (zero_extract:SI (match_dup 1) (match_dup 5) (match_dup 7)))]) + (match_dup 1)]) + ++(define_insn "*rotrsi3_cnt1" ++ [(set (match_operand:SI 0 "dest_reg_operand" "=w") ++ (rotatert:SI (match_operand:SI 1 "register_operand" "c") ++ (const_int 1)))] ++ "" ++ "ror %0,%1%&" ++ [(set_attr "type" "shift") ++ (set_attr "predicable" "no") ++ (set_attr "length" "4")]) ++ ++(define_insn "*ashlsi2_cnt1" ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") ++ (ashift:SI (match_operand:SI 1 "register_operand" "Rcqq,c") ++ (const_int 1)))] ++ "" ++ "asl%? %0,%1%&" ++ [(set_attr "type" "shift") ++ (set_attr "iscompact" "maybe,false") ++ (set_attr "predicable" "no,no")]) ++ ++(define_insn "*lshrsi3_cnt1" ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") ++ (lshiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") ++ (const_int 1)))] ++ "" ++ "lsr%? %0,%1%&" ++ [(set_attr "type" "shift") ++ (set_attr "iscompact" "maybe,false") ++ (set_attr "predicable" "no,no")]) ++ ++(define_insn "*ashrsi3_cnt1" ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,w") ++ (ashiftrt:SI (match_operand:SI 1 "register_operand" "Rcqq,c") ++ (const_int 1)))] ++ "" ++ "asr%? %0,%1%&" ++ [(set_attr "type" "shift") ++ (set_attr "iscompact" "maybe,false") ++ (set_attr "predicable" "no,no")]) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0031-Fix-option-text.patch b/toolchain/gcc/patches/6.3.0/0031-Fix-option-text.patch new file mode 100644 index 0000000..8f35b81 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0031-Fix-option-text.patch @@ -0,0 +1,44 @@ +From e1ffdb7dee37fbb8c2b4cf42d639d2550086ca5c Mon Sep 17 00:00:00 2001 +From: claziss +Date: Thu, 16 Jun 2016 10:37:37 +0000 +Subject: [PATCH 31/89] Fix option text. + +gcc/ +2016-06-16 Claudiu Zissulescu + + * config/arc/arc.opt (mtp-regno): Update text. + +git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@237519 138bc75d-0d04-0410-961f-82ee72b054a4 +--- + gcc/ChangeLog | 4 ++++ + gcc/config/arc/arc.opt | 2 +- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index bfda3c16668f..b3082d9135a9 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,7 @@ ++2016-06-16 Claudiu Zissulescu ++ ++ * config/arc/arc.opt (mtp-regno): Update text. ++ + 2016-05-02 Claudiu Zissulescu + + * config/arc/arc.md (mulsidi3): Change operand 0 predicate to +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 19c5deb095f7..15785498b34e 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -411,7 +411,7 @@ Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL) + + mtp-regno= + Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25) +-Specify thread pointer register number ++Specify thread pointer register number. + + mtp-regno=none + Target RejectNegative Var(arc_tp_regno,-1) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0032-ARC-Disable-tests-for-bare-metal.patch b/toolchain/gcc/patches/6.3.0/0032-ARC-Disable-tests-for-bare-metal.patch new file mode 100644 index 0000000..7171177 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0032-ARC-Disable-tests-for-bare-metal.patch @@ -0,0 +1,133 @@ +From f0bd3c31fc1afabece8289c42655f2582e7d393f Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 17 Jun 2016 11:04:24 +0200 +Subject: [PATCH 32/89] [ARC] Disable tests for bare-metal. + +gcc/ +2016-06-23 Claudiu Zissulescu + + * testsuite/gcc.dg/tree-prof/time-profiler-2.c: Disable test for + ARC' bare-metal. + * testsuite/g++.dg/lto/pr69589_0.C: Likewise. + * testsuite/gcc.target/arc/mtune-ARC600.c: Deleted. + * testsuite/gcc.target/arc/mtune-ARC601.c: Likewise. + * testsuite/gcc.target/arc/mtune-ARC700-xmac: Likewise. + * testsuite/gcc.target/arc/mtune-ARC700.c: Likewise. + * testsuite/gcc.target/arc/mtune-ARC725D.c: Likewise. + * testsuite/gcc.target/arc/mtune-ARC750D.c: Likewise. +--- + gcc/ChangeLog | 5 +++++ + gcc/testsuite/g++.dg/lto/pr69589_0.C | 1 + + gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c | 1 + + gcc/testsuite/gcc.target/arc/mtune-ARC600.c | 4 ---- + gcc/testsuite/gcc.target/arc/mtune-ARC601.c | 4 ---- + gcc/testsuite/gcc.target/arc/mtune-ARC700-xmac | 4 ---- + gcc/testsuite/gcc.target/arc/mtune-ARC700.c | 4 ---- + gcc/testsuite/gcc.target/arc/mtune-ARC725D.c | 4 ---- + gcc/testsuite/gcc.target/arc/mtune-ARC750D.c | 4 ---- + 9 files changed, 7 insertions(+), 24 deletions(-) + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC600.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC601.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC700-xmac + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC700.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC725D.c + delete mode 100644 gcc/testsuite/gcc.target/arc/mtune-ARC750D.c + +diff --git a/gcc/ChangeLog b/gcc/ChangeLog +index b3082d9135a9..41c1cf8278bf 100644 +--- a/gcc/ChangeLog ++++ b/gcc/ChangeLog +@@ -1,3 +1,8 @@ ++2016-06-18 Claudiu Zissulescu ++ ++ * testsuite/gcc.dg/tree-prof/time-profiler-2.c: Disable test for ++ ARC' bare-metal. ++ + 2016-06-16 Claudiu Zissulescu + + * config/arc/arc.opt (mtp-regno): Update text. +diff --git a/gcc/testsuite/g++.dg/lto/pr69589_0.C b/gcc/testsuite/g++.dg/lto/pr69589_0.C +index bbdcb73dfc74..ac98cb745fb7 100644 +--- a/gcc/testsuite/g++.dg/lto/pr69589_0.C ++++ b/gcc/testsuite/g++.dg/lto/pr69589_0.C +@@ -1,6 +1,7 @@ + // { dg-lto-do link } + // { dg-lto-options "-O2 -rdynamic" } + // { dg-extra-ld-options "-r -nostdlib" } ++// { dg-skip-if "" { "arc-*-elf*" } { "*" } { "" } } + #pragma GCC visibility push(hidden) + struct A { int &operator[] (long); }; + template struct B; +diff --git a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c +index 29c0d191afe0..d9ca7bc6132c 100644 +--- a/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c ++++ b/gcc/testsuite/gcc.dg/tree-prof/time-profiler-2.c +@@ -1,4 +1,5 @@ + /* { dg-options "-O2 -fdump-ipa-profile" } */ ++/* { dg-skip-if "" { "arc-*-elf*" } { "*" } { "" } } */ + + #include + +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC600.c b/gcc/testsuite/gcc.target/arc/mtune-ARC600.c +deleted file mode 100644 +index a483d1435cae..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC600.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC600" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC601.c b/gcc/testsuite/gcc.target/arc/mtune-ARC601.c +deleted file mode 100644 +index ed57bd7092de..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC601.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC601" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC700-xmac b/gcc/testsuite/gcc.target/arc/mtune-ARC700-xmac +deleted file mode 100644 +index 2f1e137be4d4..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC700-xmac ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC700-xmac" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC700.c b/gcc/testsuite/gcc.target/arc/mtune-ARC700.c +deleted file mode 100644 +index 851ea7305e03..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC700.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC700" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC725D.c b/gcc/testsuite/gcc.target/arc/mtune-ARC725D.c +deleted file mode 100644 +index e2aa4846291c..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC725D.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC725D" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/mtune-ARC750D.c b/gcc/testsuite/gcc.target/arc/mtune-ARC750D.c +deleted file mode 100644 +index 20923300ee12..000000000000 +--- a/gcc/testsuite/gcc.target/arc/mtune-ARC750D.c ++++ /dev/null +@@ -1,4 +0,0 @@ +-/* { dg-do compile } */ +-/* { dg-options "-mtune=ARC750D" } */ +- +-/* { dg-final { scan-assembler ".cpu ARC700" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0033-ARC-Update-INSN_LENGTH_ALIGNMENT.patch b/toolchain/gcc/patches/6.3.0/0033-ARC-Update-INSN_LENGTH_ALIGNMENT.patch new file mode 100644 index 0000000..499b1a5 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0033-ARC-Update-INSN_LENGTH_ALIGNMENT.patch @@ -0,0 +1,34 @@ +From fe4dfd7c933123e3ff0f696e1a6d2766f1c9c68e Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 20 Jun 2016 17:38:05 +0200 +Subject: [PATCH 33/89] [ARC] Update INSN_LENGTH_ALIGNMENT. + +gcc/ +2016-06-20 Claudiu Zissulescu + + * config/arc/arc.h (INSN_LENGTH_ALIGNMENT): Change. +--- + gcc/config/arc/arc.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 365062ede280..29f474db1b35 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1516,10 +1516,10 @@ extern int arc_return_address_regs[4]; + #define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE, PREFIX, NUM, TABLE) \ + ASM_OUTPUT_ALIGN ((FILE), ADDR_VEC_ALIGN (TABLE)); + +-#define INSN_LENGTH_ALIGNMENT(INSN) \ +- ((JUMP_P (INSN) \ ++#define INSN_LENGTH_ALIGNMENT(INSN) \ ++ ((JUMP_TABLE_DATA_P (INSN) \ + && GET_CODE (PATTERN (INSN)) == ADDR_DIFF_VEC \ +- && GET_MODE (PATTERN (INSN)) == QImode) \ ++ && GET_MODE (PATTERN (INSN)) == QImode) \ + ? 0 : length_unit_log) + + /* Define if operations between registers always perform the operation +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0034-ARC-Reimplement-exception-handling-support.patch b/toolchain/gcc/patches/6.3.0/0034-ARC-Reimplement-exception-handling-support.patch new file mode 100644 index 0000000..3c42032 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0034-ARC-Reimplement-exception-handling-support.patch @@ -0,0 +1,523 @@ +From a33d80531d931cc0e218e504042a98bc60a073ad Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 9 Jun 2016 15:57:24 +0200 +Subject: [PATCH 34/89] [ARC] Reimplement exception handling support. + +2016-06-09 Claudiu Zissulescu + Andrew Burgess + + * config/arc/arc-protos.h (arc_compute_frame_size): Delete + declaration. + (arc_return_slot_offset): Likewise. + (arc_eh_return_address_location): New declaration. + * config/arc/arc.c (TARGET_BUILTIN_SETJMP_FRAME_VALUE): Define. + (MUST_SAVE_REGISTER): Add exception handler case. + (MUST_SAVE_RETURN_ADDR): Likewise. + (arc_frame_pointer_required): Likewise. + (arc_frame_pointer_needed): New function. + (arc_compute_frame_size): Changed. + (arc_expand_prologue): Likewise. + (arc_expand_epilogue): Likewise. + (arc_initial_elimination_offset): Likewise. + (arc_return_slot_offset): Delete. + (arc_eh_return_address_location): New function. + (arc_builtin_setjmp_frame_value): Likewise. + * config/arc/arc.h (EH_RETURN_DATA_REGNO): Use 2 registers. + (EH_RETURN_STACKADJ_RTX): Define. + (EH_RETURN_HANDLER_RTX): Likewise. + * config/arc/arc.md (eh_return): Delete. +--- + gcc/config/arc/arc-protos.h | 4 +- + gcc/config/arc/arc.c | 249 +++++++++++++++++++++++++++++++++++--------- + gcc/config/arc/arc.h | 7 +- + gcc/config/arc/arc.md | 33 ------ + 4 files changed, 204 insertions(+), 89 deletions(-) + +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 0e9476699ee3..892b15ede31a 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -51,8 +51,6 @@ extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool); + extern enum arc_function_type arc_compute_function_type (struct function *); + #endif /* TREE_CODE */ + +- +-extern unsigned int arc_compute_frame_size (int); + extern bool arc_ccfsm_branch_deleted_p (void); + extern void arc_ccfsm_record_branch_deleted (void); + +@@ -118,8 +116,8 @@ extern bool arc_epilogue_uses (int regno); + extern bool arc_eh_uses (int regno); + /* insn-attrtab.c doesn't include reload.h, which declares regno_clobbered_p. */ + extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode, int); +-extern int arc_return_slot_offset (void); + extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int); + extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool); + extern bool insn_is_tls_gd_dispatch (rtx_insn *); + extern void arc_cpu_cpp_builtins (cpp_reader *); ++extern rtx arc_eh_return_address_location (void); +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index c2673334db5d..0c3ee90febcd 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -475,6 +475,9 @@ static void arc_finalize_pic (void); + #undef TARGET_DWARF_REGISTER_SPAN + #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span + ++#undef TARGET_BUILTIN_SETJMP_FRAME_VALUE ++#define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value ++ + /* Try to keep the (mov:DF _, reg) as early as possible so + that the dh-lr insns appear together and can + use the peephole2 pattern. */ +@@ -2171,15 +2174,80 @@ arc_compute_function_type (struct function *fun) + function changes it to access gotoff variables. + FIXME: This will not be needed if we used some arbitrary register + instead of r26. +-*/ +-#define MUST_SAVE_REGISTER(regno, interrupt_p) \ +-(((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ +- && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p))) \ +- || (flag_pic && crtl->uses_pic_offset_table \ +- && regno == PIC_OFFSET_TABLE_REGNUM) ) + +-#define MUST_SAVE_RETURN_ADDR \ +- (cfun->machine->frame_info.save_return_addr) ++ In frames that call __builtin_eh_return we should spill more ++ registers, this allows that stack unwinding code to access values ++ that are held in these registers (the stack unwinding ++ implementation only looks for register values on the stack, never, ++ in the actual register). ++ ++ However, we don't include the data registers, or the stack ++ adjustment registers here (0, 1, 2). The data registers are ++ covered by their own specific logic in the save/restore code, while ++ the stack adjustment register should not be restored. ++ ++ It's probably the case that we don't need to spill any of the ++ caller saved registers in this logic, but for now I'm leaving the ++ code like this. The number of frames that use __builtin_eh_return ++ is pretty low, so optimising them is not critical right now. */ ++ ++#define MUST_SAVE_REGISTER(regno, interrupt_p) \ ++ (((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ ++ && (df_regs_ever_live_p (regno) \ ++ && (!call_used_regs[regno] || interrupt_p))) \ ++ || (flag_pic && crtl->uses_pic_offset_table \ ++ && regno == PIC_OFFSET_TABLE_REGNUM) \ ++ || (crtl->calls_eh_return && (regno > 2 && regno < 27))) ++ ++#define MUST_SAVE_RETURN_ADDR (cfun->machine->frame_info.save_return_addr) ++ ++/* Helper function to wrap FRAME_POINTER_NEEDED. We do this as ++ FRAME_POINTER_NEEDED will not be true until the IRA (Integrated ++ Register Allocator) pass, while we want to get the frame size ++ correct earlier than the IRA pass. ++ ++ When a function uses eh_return we must ensure that the fp register ++ is saved and then restored so that the unwinder can restore the ++ correct value for the frame we are going to jump to. ++ ++ To do this we force all frames that call eh_return to require a ++ frame pointer (see changes to arc_frame_pointer_required), this ++ will ensure that the previous frame pointer is stored on entry to ++ the function, and will then be reloaded at function exit. ++ ++ As the frame pointer is handled as a special case in our prologue ++ and epilogue code it must not be saved and restored using the ++ MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC ++ believes that the function is not using a frame pointer and that ++ the value in the fp register is the frame pointer, while the ++ prologue and epilogue are busy saving and restoring the fp ++ register. This issue is fixed in this commit too. ++ ++ During compilation of a function the frame size is evaluated ++ multiple times, it is not until the reload pass is complete the the ++ frame size is considered fixed (it is at this point that space for ++ all spills has been allocated). However the frame_pointer_needed ++ variable is not set true until the register allocation pass, as a ++ result in the early stages the frame size does not include space ++ for the frame pointer to be spilled. ++ ++ The problem that this causes, that I have not yet tracked down, is ++ that the rtl generated for EH_RETURN_HANDLER_RTX uses the details ++ of the frame size to compute the offset from the frame pointer at ++ which the return address lives. However, in early passes GCC has ++ not yet realised we need a frame pointer, and so has not included ++ space for the frame pointer in the frame size, and so gets the ++ offset of the return address wrong. This should not be an issue as ++ in later passes GCC has realised that the frame pointer needs to be ++ spilled, and has increased the frame size. However, the rtl for ++ the EH_RETURN_HANDLER_RTX is not regenerated to use the newer, ++ larger offset, and the wrong smaller offset is used. */ ++ ++static bool ++arc_frame_pointer_needed (void) ++{ ++ return (frame_pointer_needed || crtl->calls_eh_return); ++} + + /* Return non-zero if there are registers to be saved or loaded using + millicode thunks. We can only use consecutive sequences starting +@@ -2211,13 +2279,11 @@ arc_compute_millicode_save_restore_regs (unsigned int gmask, + return 0; + } + +-/* Return the bytes needed to compute the frame pointer from the current +- stack pointer. +- +- SIZE is the size needed for local variables. */ ++/* Return the bytes needed to compute the frame pointer from the ++ current stack pointer. */ + +-unsigned int +-arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */ ++static unsigned int ++arc_compute_frame_size (void) + { + int regno; + unsigned int total_size, var_size, args_size, pretend_size, extra_size; +@@ -2225,14 +2291,20 @@ arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */ + unsigned int gmask; + enum arc_function_type fn_type; + int interrupt_p; +- struct arc_frame_info *frame_info = &cfun->machine->frame_info; ++ struct arc_frame_info *frame_info; ++ int size; ++ ++ /* The answer might already be known. */ ++ if (cfun->machine->frame_info.initialized) ++ return cfun->machine->frame_info.total_size; + +- size = ARC_STACK_ALIGN (size); ++ frame_info = &cfun->machine->frame_info; ++ size = ARC_STACK_ALIGN (get_frame_size ()); + +- /* 1) Size of locals and temporaries */ ++ /* 1) Size of locals and temporaries. */ + var_size = size; + +- /* 2) Size of outgoing arguments */ ++ /* 2) Size of outgoing arguments. */ + args_size = crtl->outgoing_args_size; + + /* 3) Calculate space needed for saved registers. +@@ -2255,12 +2327,29 @@ arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */ + } + } + ++ /* In a frame that calls __builtin_eh_return two data registers are ++ used to pass values back to the exception handler. ++ ++ Ensure that these registers are spilled to the stack so that the ++ exception throw code can find them, and update the saved values. ++ The handling code will then consume these reloaded values to ++ handle the exception. */ ++ if (crtl->calls_eh_return) ++ for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++) ++ { ++ reg_size += UNITS_PER_WORD; ++ gmask |= 1 << regno; ++ } ++ + /* 4) Space for back trace data structure. + (if required) + (if required). */ + frame_info->save_return_addr +- = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM)); ++ = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM) ++ || crtl->calls_eh_return); + /* Saving blink reg in case of leaf function for millicode thunk calls. */ +- if (optimize_size && !TARGET_NO_MILLICODE_THUNK_SET) ++ if (optimize_size ++ && !TARGET_NO_MILLICODE_THUNK_SET ++ && !crtl->calls_eh_return) + { + if (arc_compute_millicode_save_restore_regs (gmask, frame_info)) + frame_info->save_return_addr = true; +@@ -2269,7 +2358,7 @@ arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */ + extra_size = 0; + if (MUST_SAVE_RETURN_ADDR) + extra_size = 4; +- if (frame_pointer_needed) ++ if (arc_frame_pointer_needed ()) + extra_size += 4; + + /* 5) Space for variable arguments passed in registers */ +@@ -2288,13 +2377,17 @@ arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */ + /* Compute total frame size. */ + total_size = var_size + args_size + extra_size + pretend_size + reg_size; + +- total_size = ARC_STACK_ALIGN (total_size); ++ /* It used to be the case that the alignment was forced at this ++ point. However, that is dangerous, calculations based on ++ total_size would be wrong. Given that this has never cropped up ++ as an issue I've changed this to an assert for now. */ ++ gcc_assert (total_size == ARC_STACK_ALIGN (total_size)); + + /* Compute offset of register save area from stack pointer: + Frame: pretend_size reg_size var_size args_size <--sp + */ + reg_offset = (total_size - (pretend_size + reg_size + extra_size) +- + (frame_pointer_needed ? 4 : 0)); ++ + (arc_frame_pointer_needed ()? 4 : 0)); + + /* Save computed information. */ + frame_info->total_size = total_size; +@@ -2490,7 +2583,7 @@ int arc_return_address_regs[4] + void + arc_expand_prologue (void) + { +- int size = get_frame_size (); ++ int size; + unsigned int gmask = cfun->machine->frame_info.gmask; + /* unsigned int frame_pointer_offset;*/ + unsigned int frame_size_to_allocate; +@@ -2499,12 +2592,8 @@ arc_expand_prologue (void) + PRE_MODIFY, thus enabling more short insn generation.) */ + int first_offset = 0; + +- size = ARC_STACK_ALIGN (size); +- +- /* Compute/get total frame size. */ +- size = (!cfun->machine->frame_info.initialized +- ? arc_compute_frame_size (size) +- : cfun->machine->frame_info.total_size); ++ /* Compute total frame size. */ ++ size = arc_compute_frame_size (); + + if (flag_stack_usage_info) + current_function_static_stack_size = size; +@@ -2548,7 +2637,7 @@ arc_expand_prologue (void) + + + /* Save frame pointer if needed. */ +- if (frame_pointer_needed) ++ if (arc_frame_pointer_needed ()) + { + rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (-UNITS_PER_WORD + first_offset)); +@@ -2583,13 +2672,10 @@ arc_expand_prologue (void) + void + arc_expand_epilogue (int sibcall_p) + { +- int size = get_frame_size (); ++ int size; + enum arc_function_type fn_type = arc_compute_function_type (cfun); + +- size = ARC_STACK_ALIGN (size); +- size = (!cfun->machine->frame_info.initialized +- ? arc_compute_frame_size (size) +- : cfun->machine->frame_info.total_size); ++ size = arc_compute_frame_size (); + + unsigned int pretend_size = cfun->machine->frame_info.pretend_size; + unsigned int frame_size; +@@ -2612,13 +2698,13 @@ arc_expand_epilogue (int sibcall_p) + sp, but don't restore sp if we don't have to. */ + + if (!can_trust_sp_p) +- gcc_assert (frame_pointer_needed); ++ gcc_assert (arc_frame_pointer_needed ()); + + /* Restore stack pointer to the beginning of saved register area for + ARCompact ISA. */ + if (frame_size) + { +- if (frame_pointer_needed) ++ if (arc_frame_pointer_needed ()) + frame_move (stack_pointer_rtx, frame_pointer_rtx); + else + first_offset = frame_size; +@@ -2629,7 +2715,7 @@ arc_expand_epilogue (int sibcall_p) + + + /* Restore any saved registers. */ +- if (frame_pointer_needed) ++ if (arc_frame_pointer_needed ()) + { + rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx); + +@@ -2752,21 +2838,59 @@ arc_expand_epilogue (int sibcall_p) + if (size > restored) + frame_stack_add (size - restored); + ++ /* For frames that use __builtin_eh_return, the register defined by ++ EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths. ++ On eh_return paths however, the register is set to the value that ++ should be added to the stack pointer in order to restore the ++ correct stack pointer for the exception handling frame. ++ ++ For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add ++ this onto the stack for eh_return frames. */ ++ if (crtl->calls_eh_return) ++ emit_insn (gen_add2_insn (stack_pointer_rtx, ++ EH_RETURN_STACKADJ_RTX)); ++ + /* Emit the return instruction. */ + if (sibcall_p == FALSE) + emit_jump_insn (gen_simple_return ()); + } + +-/* Return the offset relative to the stack pointer where the return address +- is stored, or -1 if it is not stored. */ +- +-int +-arc_return_slot_offset () +-{ +- struct arc_frame_info *afi = &cfun->machine->frame_info; ++/* Return rtx for the location of the return address on the stack, ++ suitable for use in __builtin_eh_return. The new return address ++ will be written to this location in order to redirect the return to ++ the exception handler. */ + +- return (afi->save_return_addr +- ? afi->total_size - afi->pretend_size - afi->extra_size : -1); ++rtx ++arc_eh_return_address_location (void) ++{ ++ rtx mem; ++ int offset; ++ struct arc_frame_info *afi; ++ ++ arc_compute_frame_size (); ++ afi = &cfun->machine->frame_info; ++ ++ gcc_assert (crtl->calls_eh_return); ++ gcc_assert (afi->save_return_addr); ++ gcc_assert (afi->extra_size >= 4); ++ ++ /* The '-4' removes the size of the return address, which is ++ included in the 'extra_size' field. */ ++ offset = afi->reg_size + afi->extra_size - 4; ++ mem = gen_frame_mem (Pmode, ++ plus_constant (Pmode, frame_pointer_rtx, offset)); ++ ++ /* The following should not be needed, and is, really a hack. The ++ issue being worked around here is that the DSE (Dead Store ++ Elimination) pass will remove this write to the stack as it sees ++ a single store and no corresponding read. The read however ++ occurs in the epilogue code, which is not added into the function ++ rtl until a later pass. So, at the time of DSE, the decision to ++ remove this store seems perfectly sensible. Marking the memory ++ address as volatile obviously has the effect of preventing DSE ++ from removing the store. */ ++ MEM_VOLATILE_P (mem) = 1; ++ return mem; + } + + /* PIC */ +@@ -4320,8 +4444,8 @@ arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) + int + arc_initial_elimination_offset (int from, int to) + { +- if (! cfun->machine->frame_info.initialized) +- arc_compute_frame_size (get_frame_size ()); ++ if (!cfun->machine->frame_info.initialized) ++ arc_compute_frame_size (); + + if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM) + { +@@ -4349,7 +4473,7 @@ arc_initial_elimination_offset (int from, int to) + static bool + arc_frame_pointer_required (void) + { +- return cfun->calls_alloca; ++ return cfun->calls_alloca || crtl->calls_eh_return; + } + + +@@ -10059,6 +10183,29 @@ compact_memory_operand_p (rtx op, machine_mode mode, + return false; + } + ++ ++/* Return the frame pointer value to be backed up in the setjmp buffer. */ ++ ++static rtx ++arc_builtin_setjmp_frame_value (void) ++{ ++ /* We always want to preserve whatever value is currently in the frame ++ pointer register. For frames that are using the frame pointer the new ++ value of the frame pointer register will have already been computed ++ (as part of the prologue). For frames that are not using the frame ++ pointer it is important that we backup whatever value is in the frame ++ pointer register, as earlier (more outer) frames may have placed a ++ value into the frame pointer register. It might be tempting to try ++ and use `frame_pointer_rtx` here, however, this is not what we want. ++ For frames that are using the frame pointer this will give the ++ correct value. However, for frames that are not using the frame ++ pointer this will still give the value that _would_ have been the ++ frame pointer value for this frame (if the use of the frame pointer ++ had not been removed). We really do want the raw frame pointer ++ register value. */ ++ return gen_raw_REG (Pmode, FRAME_POINTER_REGNUM); ++} ++ + struct gcc_target targetm = TARGET_INITIALIZER; + + #include "gt-arc.h" +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 29f474db1b35..d2adf4d8f1bb 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1474,8 +1474,11 @@ extern int arc_return_address_regs[4]; + #define DWARF2_UNWIND_INFO 0 + #endif + +-#define EH_RETURN_DATA_REGNO(N) \ +- ((N) < 4 ? (N) : INVALID_REGNUM) ++#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) : INVALID_REGNUM) ++ ++#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 2) ++ ++#define EH_RETURN_HANDLER_RTX arc_eh_return_address_location () + + /* Turn off splitting of long stabs. */ + #define DBX_CONTIN_LENGTH 0 +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 64afb8bf7bf6..7d9d232e7e61 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -4828,39 +4828,6 @@ + (const_int 4)] + (const_int 2)))]) + +-(define_insn_and_split "eh_return" +- [(eh_return) +- (use (match_operand:SI 0 "move_src_operand" "rC32,mCalCpc")) +- (clobber (match_scratch:SI 1 "=X,r")) +- (clobber (match_scratch:SI 2 "=&r,r"))] +- "" +- "#" +- "reload_completed" +- [(set (match_dup 2) (match_dup 0))] +-{ +- int offs = arc_return_slot_offset (); +- +- if (offs < 0) +- operands[2] = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); +- else +- { +- if (!register_operand (operands[0], Pmode) +- && !satisfies_constraint_C32 (operands[0])) +- { +- emit_move_insn (operands[1], operands[0]); +- operands[0] = operands[1]; +- } +- rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs); +- if (!strict_memory_address_p (Pmode, addr)) +- { +- emit_move_insn (operands[2], addr); +- addr = operands[2]; +- } +- operands[2] = gen_frame_mem (Pmode, addr); +- } +-} +- [(set_attr "length" "12")]) +- + ;; ??? #ifdefs in function.c require the presence of this pattern, with a + ;; non-constant predicate. + (define_expand "return" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0035-ARC-Fix-mul32x16-patterns.patch b/toolchain/gcc/patches/6.3.0/0035-ARC-Fix-mul32x16-patterns.patch new file mode 100644 index 0000000..1961ba9 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0035-ARC-Fix-mul32x16-patterns.patch @@ -0,0 +1,56 @@ +From 9743f5d060948aea986456cdfa07fc11e20e3727 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 28 Jun 2016 15:05:17 +0200 +Subject: [PATCH 35/89] [ARC] Fix mul32x16 patterns. + +gcc/ +2016-06-28 Claudiu Zissulescu + + * config/arc/arc.md (umul_600): Change. + (umul64_600): Likewise. +--- + gcc/config/arc/arc.md | 18 +++++++----------- + 1 file changed, 7 insertions(+), 11 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 7d9d232e7e61..7d6d1fcfaefe 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -1937,13 +1937,11 @@ + (const_int 0)))) + (clobber (match_operand:SI 3 "acc1_operand" ""))] + "TARGET_MULMAC_32BY16_SET" +- "@mululw 0, %0, %1 +- mululw 0, %0, %1 +- mululw%? 0, %1, %0" ++ "mululw 0, %0, %1" + [(set_attr "length" "4,4,8") +- (set_attr "type" "mulmac_600, mulmac_600, mulmac_600") +- (set_attr "predicable" "no, no, yes") +- (set_attr "cond" "nocond, canuse_limm, canuse")]) ++ (set_attr "type" "mulmac_600") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) + + (define_insn "mac_600" + [(set (match_operand:SI 2 "acc2_operand" "") +@@ -2372,13 +2370,11 @@ + (const_int 0)))) + ] + "TARGET_MULMAC_32BY16_SET" +- "@mululw 0, %0, %1 +- mululw 0, %0, %1 +- mululw%? 0, %1, %0" ++ "mululw 0, %0, %1" + [(set_attr "length" "4,4,8") + (set_attr "type" "mulmac_600") +- (set_attr "predicable" "no,no,yes") +- (set_attr "cond" "nocond, canuse_limm, canuse")]) ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) + + + (define_insn "umac64_600" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0036-ARC-Cleanup-implementation.patch b/toolchain/gcc/patches/6.3.0/0036-ARC-Cleanup-implementation.patch new file mode 100644 index 0000000..26218d7 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0036-ARC-Cleanup-implementation.patch @@ -0,0 +1,201 @@ +From f5bcabb00a01fa1aa4abb2254493fb44f23a9975 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 30 Jun 2016 12:19:27 +0200 +Subject: [PATCH 36/89] [ARC] Cleanup implementation. + +gcc/ +2016-06-30 Claudiu Zissulescu + + * config/arc/arc-protos.h (insn_is_tls_gd_dispatch): Remove. + * config/arc/arc.c (arc_unspec_offset): New function. + (arc_finalize_pic): Change. + (arc_emit_call_tls_get_addr): Likewise. + (arc_legitimize_tls_address): Likewise. + (arc_legitimize_pic_address): Likewise. + (insn_is_tls_gd_dispatch): Remove. + * config/arc/arc.h (INSN_REFERENCES_ARE_DELAYED): Change. + * config/arc/arc.md (ls_gd_load): Remove. + (tls_gd_dispatch): Likewise. +--- + gcc/config/arc/arc-protos.h | 1 - + gcc/config/arc/arc.c | 41 ++++++++++++++++++----------------------- + gcc/config/arc/arc.h | 2 +- + gcc/config/arc/arc.md | 34 ---------------------------------- + 4 files changed, 19 insertions(+), 59 deletions(-) + +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 892b15ede31a..ffc715f2e82a 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -118,6 +118,5 @@ extern bool arc_eh_uses (int regno); + extern int regno_clobbered_p (unsigned int, rtx_insn *, machine_mode, int); + extern bool arc_legitimize_reload_address (rtx *, machine_mode, int, int); + extern void arc_secondary_reload_conv (rtx, rtx, rtx, bool); +-extern bool insn_is_tls_gd_dispatch (rtx_insn *); + extern void arc_cpu_cpp_builtins (cpp_reader *); + extern rtx arc_eh_return_address_location (void); +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 0c3ee90febcd..b0b21ad8b59f 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -2895,6 +2895,15 @@ arc_eh_return_address_location (void) + + /* PIC */ + ++/* Helper to generate unspec constant. */ ++ ++static rtx ++arc_unspec_offset (rtx loc, int unspec) ++{ ++ return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc), ++ unspec)); ++} ++ + /* Emit special PIC prologues and epilogues. */ + /* If the function has any GOTOFF relocations, then the GOTBASE + register has to be setup in the prologue +@@ -2920,9 +2929,7 @@ arc_finalize_pic (void) + gcc_assert (flag_pic != 0); + + pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC"); +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, pat), ARC_UNSPEC_GOT); +- pat = gen_rtx_CONST (Pmode, pat); +- ++ pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT); + pat = gen_rtx_SET (baseptr_rtx, pat); + + emit_insn (pat); +@@ -4991,8 +4998,7 @@ arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv) + + start_sequence (); + +- rtx x = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, sym), reloc); +- x = gen_rtx_CONST (Pmode, x); ++ rtx x = arc_unspec_offset (sym, reloc); + emit_move_insn (r0, x); + use_reg (&call_fusage, r0); + +@@ -5048,17 +5054,18 @@ arc_legitimize_tls_address (rtx addr, enum tls_model model) + addr = gen_rtx_CONST (Pmode, addr); + base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC); + return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr); ++ + case TLS_MODEL_GLOBAL_DYNAMIC: + return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr); ++ + case TLS_MODEL_INITIAL_EXEC: +- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_IE); +- addr = gen_rtx_CONST (Pmode, addr); ++ addr = arc_unspec_offset (addr, UNSPEC_TLS_IE); + addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr)); + return gen_rtx_PLUS (Pmode, arc_get_tp (), addr); ++ + case TLS_MODEL_LOCAL_EXEC: + local_exec: +- addr = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_TLS_OFF); +- addr = gen_rtx_CONST (Pmode, addr); ++ addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF); + return gen_rtx_PLUS (Pmode, arc_get_tp (), addr); + default: + gcc_unreachable (); +@@ -5089,14 +5096,11 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + else if (!flag_pic) + return orig; + else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr)) +- return gen_rtx_CONST (Pmode, +- gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), +- ARC_UNSPEC_GOTOFFPC)); ++ return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC); + + /* This symbol must be referenced via a load from the Global + Offset Table (@GOTPC). */ +- pat = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), ARC_UNSPEC_GOT); +- pat = gen_rtx_CONST (Pmode, pat); ++ pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT); + pat = gen_const_mem (Pmode, pat); + + if (oldx == NULL) +@@ -10034,15 +10038,6 @@ arc_dwarf_register_span (rtx rtl) + return p; + } + +-/* We can't inline this in INSN_REFERENCES_ARE_DELAYED because +- resource.h doesn't include the required header files. */ +- +-bool +-insn_is_tls_gd_dispatch (rtx_insn *insn) +-{ +- return recog_memoized (insn) == CODE_FOR_tls_gd_dispatch; +-} +- + /* Return true if OP is an acceptable memory operand for ARCompact + 16-bit load instructions of MODE. + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index d2adf4d8f1bb..6a579eba014c 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1617,7 +1617,7 @@ extern enum arc_function_type arc_compute_function_type (struct function *); + && (get_attr_type (X) == TYPE_CALL || get_attr_type (X) == TYPE_SFUNC)) + + #define INSN_REFERENCES_ARE_DELAYED(insn) \ +- (INSN_SETS_ARE_DELAYED (insn) && !insn_is_tls_gd_dispatch (insn)) ++ (INSN_SETS_ARE_DELAYED (insn)) + + #define CALL_ATTR(X, NAME) \ + ((CALL_P (X) || NONJUMP_INSN_P (X)) \ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 7d6d1fcfaefe..f9080fb1eb48 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -5394,21 +5394,6 @@ + [(set_attr "is_sfunc" "yes") + (set_attr "predicable" "yes")]) + +-(define_insn "tls_gd_load" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,c") +- (unspec:SI [(match_operand:SI 1 "register_operand" "Rcq#q,c") +- (match_operand:SI 2 "symbolic_operand" "X,X")] +- UNSPEC_TLS_GD))] +- "" +- ".tls_gd_ld %2`ld%? %0,[%1]" +- [(set_attr "type" "load") +- ; if the linker has to patch this into IE, we need a long insn +- ; (FIXME: or two short insn, ld_s / jl_s. missing -Os optimization.) +- (set_attr_alternative "iscompact" +- [(cond [(ne (symbol_ref "arc_tp_regno == 30") (const_int 0)) +- (const_string "*")] (const_string "maybe")) +- (const_string "*")])]) +- + (define_insn "tls_gd_get_addr" + [(set (reg:SI R0_REG) + (call:SI (mem:SI (unspec:SI [(match_operand:SI 0 +@@ -5422,25 +5407,6 @@ + ; With TARGET_MEDIUM_CALLS, plt calls are not predicable. + (set_attr "predicable" "no")]) + +-; We make this call specific to the tls symbol to avoid commoning this +-; with calls for other symbols; we want the linker to be able to +-(define_insn "tls_gd_dispatch" +- [(set (reg:SI R0_REG) +- (unspec:SI +- [(reg:SI R0_REG) +- (call (mem:SI (match_operand:SI 0 "register_operand" "Rcq,q,c")) +- (const_int 0)) +- (match_operand:SI 1 "symbolic_operand" "X,X,X")] +- UNSPEC_TLS_GD)) +- (clobber (reg:SI RETURN_ADDR_REGNUM)) +- (clobber (reg:DI R10_REG)) +- (clobber (reg:SI R12_REG))] +- "" +- ".tls_gd_call %1`jl%!%* [%0]" +- [(set_attr "type" "call") +- (set_attr "iscompact" "maybe,false,*") +- (set_attr "predicable" "no,no,yes")]) +- + ;; For thread pointer builtins + (define_expand "get_thread_pointersi" + [(set (match_operand:SI 0 "register_operand") (match_dup 1))] +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0037-ARC-Refurbish-mul64-support.patch b/toolchain/gcc/patches/6.3.0/0037-ARC-Refurbish-mul64-support.patch new file mode 100644 index 0000000..ddf03ad --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0037-ARC-Refurbish-mul64-support.patch @@ -0,0 +1,126 @@ +From 632130f0ad0f825bb2faeea997018258a4510fb2 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 4 Jul 2016 11:11:50 +0200 +Subject: [PATCH 37/89] [ARC] Refurbish mul64 support. + +gcc/ +2016-07-04 Claudiu Zissulescu + + * config/arc/arc.md (mulsidi_600): Changed. + (umulsidi_600): Likewise. + (mul64): New pattern. + (mulu64): Likewise. + (mulsidi3): Changed. + (umulsidi3): Likewise. +--- + gcc/config/arc/arc.md | 64 ++++++++++++++++++++++++++++++++------------------- + 1 file changed, 40 insertions(+), 24 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index f9080fb1eb48..cfa55dac5423 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -12,10 +12,6 @@ + ;; Profiling support and performance improvements by + ;; Joern Rennecke (joern.rennecke@embecosm.com) + ;; +-;; Support for DSP multiply instructions and mul64 +-;; instructions for ARC600; and improvements in flag setting +-;; instructions by +-;; Muhammad Khurram Riaz (Khurram.Riaz@arc.com) + + ;; This file is part of GCC. + +@@ -2011,14 +2007,26 @@ + [(set_attr "is_sfunc" "yes") + (set_attr "predicable" "yes")]) + +-(define_insn "mulsidi_600" ++(define_insn_and_split "mulsidi_600" ++ [(set (match_operand:DI 0 "register_operand" "=c, c,c, c") ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%Rcq#q, c,c, c")) ++ (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "Rcq#q,cL,L,C32")))) ++ (clobber (reg:DI MUL64_OUT_REG))] ++ "TARGET_MUL64_SET" ++ "#" ++ "TARGET_MUL64_SET" ++ [(const_int 0)] ++ "emit_insn (gen_mul64 (operands[1], operands[2])); ++ emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); ++ DONE;" ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++ ++(define_insn "mul64" + [(set (reg:DI MUL64_OUT_REG) +- (mult:DI (sign_extend:DI +- (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c")) +- (sign_extend:DI +-; assembler issue for "I", see mulsi_600 +-; (match_operand:SI 1 "register_operand" "Rcq#q,cL,I,Cal"))))] +- (match_operand:SI 1 "register_operand" "Rcq#q,cL,L,C32"))))] ++ (mult:DI ++ (sign_extend:DI (match_operand:SI 0 "register_operand" "%Rcq#q, c,c, c")) ++ (sign_extend:DI (match_operand:SI 1 "nonmemory_operand" "Rcq#q,cL,L,C32"))))] + "TARGET_MUL64_SET" + "mul64%? \t0, %0, %1%&" + [(set_attr "length" "*,4,4,8") +@@ -2027,14 +2035,26 @@ + (set_attr "predicable" "yes,yes,no,yes") + (set_attr "cond" "canuse,canuse,canuse_limm,canuse")]) + +-(define_insn "umulsidi_600" ++(define_insn_and_split "umulsidi_600" ++ [(set (match_operand:DI 0 "register_operand" "=c,c, c") ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c,c, c")) ++ (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" "cL,L,C32")))) ++ (clobber (reg:DI MUL64_OUT_REG))] ++ "TARGET_MUL64_SET" ++ "#" ++ "TARGET_MUL64_SET" ++ [(const_int 0)] ++ "emit_insn (gen_mulu64 (operands[1], operands[2])); ++ emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); ++ DONE;" ++ [(set_attr "type" "umulti") ++ (set_attr "length" "8")]) ++ ++(define_insn "mulu64" + [(set (reg:DI MUL64_OUT_REG) +- (mult:DI (zero_extend:DI +- (match_operand:SI 0 "register_operand" "%c,c,c")) +- (sign_extend:DI +-; assembler issue for "I", see mulsi_600 +-; (match_operand:SI 1 "register_operand" "cL,I,Cal"))))] +- (match_operand:SI 1 "register_operand" "cL,L,C32"))))] ++ (mult:DI ++ (zero_extend:DI (match_operand:SI 0 "register_operand" "%c,c,c")) ++ (zero_extend:DI (match_operand:SI 1 "nonmemory_operand" "cL,L,C32"))))] + "TARGET_MUL64_SET" + "mulu64%? \t0, %0, %1%&" + [(set_attr "length" "4,4,8") +@@ -2098,9 +2118,7 @@ + } + else if (TARGET_MUL64_SET) + { +- operands[2] = force_reg (SImode, operands[2]); +- emit_insn (gen_mulsidi_600 (operands[1], operands[2])); +- emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); ++ emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2])); + DONE; + } + else if (TARGET_MULMAC_32BY16_SET) +@@ -2332,9 +2350,7 @@ + } + else if (TARGET_MUL64_SET) + { +- operands[2] = force_reg (SImode, operands[2]); +- emit_insn (gen_umulsidi_600 (operands[1], operands[2])); +- emit_move_insn (operands[0], gen_rtx_REG (DImode, MUL64_OUT_REG)); ++ emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2])); + DONE; + } + else if (TARGET_MULMAC_32BY16_SET) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0038-ARC-Fix-PIE.patch b/toolchain/gcc/patches/6.3.0/0038-ARC-Fix-PIE.patch new file mode 100644 index 0000000..72c757d --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0038-ARC-Fix-PIE.patch @@ -0,0 +1,100 @@ +From 71d9c8f986cf522d4088f98203084911f79da2fd Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 27 Jul 2016 15:43:33 +0200 +Subject: [PATCH 38/89] [ARC] Fix PIE. + +gcc/ +2016-07-27 Cupertino Miranda + + * config/arc/arc.h (STARTFILE_SPEC): Use default linux specs. + (ENDFILE_SPEC): Likewise. + +libgcc/ +2016-07-27 Cupertino Miranda + + * config.host (arc*-*-linux-uclibc*): Use default extra + objects. Include linux-android header. + * config/arc/crti.S (_init): Declare symbol as function. + (_fini): Likewise. +--- + gcc/config.gcc | 2 +- + gcc/config/arc/arc.h | 10 ++++------ + libgcc/config.host | 4 ++-- + libgcc/config/arc/crti.S | 2 ++ + 4 files changed, 9 insertions(+), 9 deletions(-) + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index fbf77d3e6347..7b6138aec6bf 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -1025,7 +1025,7 @@ arc*-*-elf*) + ;; + arc*-*-linux-uclibc*) + extra_headers="arc-simd.h" +- tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file}" ++ tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file}" + tmake_file="${tmake_file} arc/t-uClibc arc/t-arc" + tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0" + tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1" +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 6a579eba014c..d4cc20ddf708 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -138,17 +138,15 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + #define STARTFILE_SPEC "%{!shared:crt0.o%s} crti%O%s %{pg|p:crtg.o%s} " \ + "%(arc_tls_extra_start_spec) crtbegin.o%s" + #else +-#define STARTFILE_SPEC "%{!shared:%{!mkernel:crt1.o%s}} crti.o%s \ +- %{!shared:%{pg|p|profile:crtg.o%s} crtbegin.o%s} %{shared:crtbeginS.o%s}" +- ++#define STARTFILE_SPEC \ ++ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, ANDROID_STARTFILE_SPEC) + #endif + + #if DEFAULT_LIBC != LIBC_UCLIBC + #define ENDFILE_SPEC "%{pg|p:crtgend.o%s} crtend.o%s crtn%O%s" + #else +-#define ENDFILE_SPEC "%{!shared:%{pg|p|profile:crtgend.o%s} crtend.o%s} \ +- %{shared:crtendS.o%s} crtn.o%s" +- ++#define ENDFILE_SPEC \ ++ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC) + #endif + + #if DEFAULT_LIBC == LIBC_UCLIBC +diff --git a/libgcc/config.host b/libgcc/config.host +index 4e02765fce74..5102eee42931 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -371,8 +371,8 @@ arc*-*-elf*) + ;; + arc*-*-linux-uclibc*) + tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc700-uClibc arc/t-arc" +- extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o" +- extra_parts="${extra_parts} crttls.o" ++ extra_parts="$extra_parts crti.o crtn.o libgmon.a crtg.o crtgend.o" ++ extra_parts="$extra_parts crttls.o" + ;; + arm-wrs-vxworks) + tmake_file="$tmake_file arm/t-arm arm/t-elf t-softfp-sfdf t-softfp-excl arm/t-softfp t-softfp" +diff --git a/libgcc/config/arc/crti.S b/libgcc/config/arc/crti.S +index 7f643056c964..6867ca99e839 100644 +--- a/libgcc/config/arc/crti.S ++++ b/libgcc/config/arc/crti.S +@@ -31,11 +31,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + .section .init + .global _init + .word 0 ++ .type _init,@function + _init: + push_s blink + + .section .fini + .global _fini + .word 0 ++ .type _fini,@function + _fini: + push_s blink +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0039-ARC-Generating-code-for-profiling.patch b/toolchain/gcc/patches/6.3.0/0039-ARC-Generating-code-for-profiling.patch new file mode 100644 index 0000000..70b254b --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0039-ARC-Generating-code-for-profiling.patch @@ -0,0 +1,2136 @@ +From 9351fca2ef0932f9877c93a74de9cbabcc1aaed4 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 28 Jul 2016 11:13:00 +0200 +Subject: [PATCH 39/89] [ARC] Generating code for profiling. + +gcc/ +2016-07-28 Claudiu Zissulescu + + * config/arc/arc.h (LINK_SPEC): Tidy up. + (ENDFILE_SPEC): Likewise. + (LIB_SPEC): Likewise. + (STARTFILE_SPEC): Include gcrt0 when profiling. + (FUNCTION_PROFILER): Use __mcount. + * config/arc/arc.opt (mucb-mcount): Remove. + * doc/invoke.texi (ARC): Remove mucb-mcount doc. + * arc/arc-protos.h (arc_profile_call): Remove. + * arc/arc.c (write_profile_sections): Likewise. + (arc_profile_call): Likewise. + (unspec_prof_hash): Likewise. + (unspec_prof_htab_eq): Likewise. + (arc_legitimate_constant_p): Remove UNSPEC_PROF. + (arc_reorg): Remove call to write_profile_sections. + * arc/arc.md (call): Remove call to arc_profile_call. + (call_value): Likewise. + (sibcall): Likewise. + (sibcall_value): Likewise. + (define_constants): Remove UNSPEC_PROF. + +libgcc/ +2016-07-28 Claudiu Zissulescu + + * config.host (arc*-*-linux-uclibc*): Remove libgmon, crtg, and + crtgend. + (arc*-*-elf*): Likewise. + * config/arc/t-arc: Remove old gmon lib targets. + * arc/crtg.S: Reomve. + * arc/crtgend.S: Likewise. + * arc/gmon/atomic.h: Likewise. + * arc/gmon/auxreg.h: Likewise. + * arc/gmon/dcache_linesz.S: Likewise. + * arc/gmon/gmon.c: Likewise. + * arc/gmon/machine-gmon.h: Likewise. + * arc/gmon/mcount.c: Likewise. + * arc/gmon/prof-freq-stub.S: Likewise. + * arc/gmon/prof-freq.c: Likewise. + * arc/gmon/profil.S: Likewise. + * arc/gmon/sys/gmon.h: Likewise. + * arc/gmon/sys/gmon_out.h: Likewise. + * arc/t-arc-newlib: Likewise. + * arc/t-arc700-uClibc: Renamed to t-arc-uClibc. +--- + gcc/config/arc/arc-protos.h | 1 - + gcc/config/arc/arc.c | 152 ------- + gcc/config/arc/arc.h | 28 +- + gcc/config/arc/arc.md | 35 +- + gcc/config/arc/arc.opt | 4 - + gcc/doc/invoke.texi | 8 +- + libgcc/config.host | 10 +- + libgcc/config/arc/crtg.S | 51 --- + libgcc/config/arc/crtgend.S | 33 -- + libgcc/config/arc/gmon/atomic.h | 26 -- + libgcc/config/arc/gmon/auxreg.h | 35 -- + libgcc/config/arc/gmon/dcache_linesz.S | 57 --- + libgcc/config/arc/gmon/gmon.c | 450 --------------------- + libgcc/config/arc/gmon/machine-gmon.h | 65 --- + libgcc/config/arc/gmon/mcount.c | 206 ---------- + libgcc/config/arc/gmon/prof-freq-stub.S | 40 -- + libgcc/config/arc/gmon/prof-freq.c | 60 --- + libgcc/config/arc/gmon/profil.S | 164 -------- + libgcc/config/arc/gmon/sys/gmon.h | 217 ---------- + libgcc/config/arc/gmon/sys/gmon_out.h | 55 --- + libgcc/config/arc/t-arc | 37 -- + libgcc/config/arc/t-arc-newlib | 22 - + .../config/arc/{t-arc700-uClibc => t-arc-uClibc} | 2 - + 23 files changed, 22 insertions(+), 1736 deletions(-) + delete mode 100644 libgcc/config/arc/crtg.S + delete mode 100644 libgcc/config/arc/crtgend.S + delete mode 100644 libgcc/config/arc/gmon/atomic.h + delete mode 100644 libgcc/config/arc/gmon/auxreg.h + delete mode 100644 libgcc/config/arc/gmon/dcache_linesz.S + delete mode 100644 libgcc/config/arc/gmon/gmon.c + delete mode 100644 libgcc/config/arc/gmon/machine-gmon.h + delete mode 100644 libgcc/config/arc/gmon/mcount.c + delete mode 100644 libgcc/config/arc/gmon/prof-freq-stub.S + delete mode 100644 libgcc/config/arc/gmon/prof-freq.c + delete mode 100644 libgcc/config/arc/gmon/profil.S + delete mode 100644 libgcc/config/arc/gmon/sys/gmon.h + delete mode 100644 libgcc/config/arc/gmon/sys/gmon_out.h + delete mode 100644 libgcc/config/arc/t-arc-newlib + rename libgcc/config/arc/{t-arc700-uClibc => t-arc-uClibc} (98%) + +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index ffc715f2e82a..2c11f3557bf2 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -68,7 +68,6 @@ extern bool arc_raw_symbolic_reference_mentioned_p (rtx, bool); + extern bool arc_legitimate_pic_operand_p (rtx); + extern bool arc_is_longcall_p (rtx); + extern bool arc_is_shortcall_p (rtx); +-extern bool arc_profile_call (rtx callee); + extern bool valid_brcc_with_delay_p (rtx *); + extern bool small_data_pattern (rtx , machine_mode); + extern rtx arc_rewrite_small_data (rtx); +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index b0b21ad8b59f..4e478131da35 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -3733,97 +3733,6 @@ arc_print_operand_address (FILE *file , rtx addr) + } + } + +-/* Called via walk_stores. DATA points to a hash table we can use to +- establish a unique SYMBOL_REF for each counter, which corresponds to +- a caller-callee pair. +- X is a store which we want to examine for an UNSPEC_PROF, which +- would be an address loaded into a register, or directly used in a MEM. +- If we found an UNSPEC_PROF, if we encounter a new counter the first time, +- write out a description and a data allocation for a 32 bit counter. +- Also, fill in the appropriate symbol_ref into each UNSPEC_PROF instance. */ +- +-static void +-write_profile_sections (rtx dest ATTRIBUTE_UNUSED, rtx x, void *data) +-{ +- rtx *srcp, src; +- htab_t htab = (htab_t) data; +- rtx *slot; +- +- if (GET_CODE (x) != SET) +- return; +- srcp = &SET_SRC (x); +- if (MEM_P (*srcp)) +- srcp = &XEXP (*srcp, 0); +- else if (MEM_P (SET_DEST (x))) +- srcp = &XEXP (SET_DEST (x), 0); +- src = *srcp; +- if (GET_CODE (src) != CONST) +- return; +- src = XEXP (src, 0); +- if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_PROF) +- return; +- +- gcc_assert (XVECLEN (src, 0) == 3); +- if (!htab_elements (htab)) +- { +- output_asm_insn (".section .__arc_profile_desc, \"a\"\n" +- "\t.long %0 + 1\n", +- &XVECEXP (src, 0, 0)); +- } +- slot = (rtx *) htab_find_slot (htab, src, INSERT); +- if (*slot == HTAB_EMPTY_ENTRY) +- { +- static int count_nr; +- char buf[24]; +- rtx count; +- +- *slot = src; +- sprintf (buf, "__prof_count%d", count_nr++); +- count = gen_rtx_SYMBOL_REF (Pmode, xstrdup (buf)); +- XVECEXP (src, 0, 2) = count; +- output_asm_insn (".section\t.__arc_profile_desc, \"a\"\n" +- "\t.long\t%1\n" +- "\t.section\t.__arc_profile_counters, \"aw\"\n" +- "\t.type\t%o2, @object\n" +- "\t.size\t%o2, 4\n" +- "%o2:\t.zero 4", +- &XVECEXP (src, 0, 0)); +- *srcp = count; +- } +- else +- *srcp = XVECEXP (*slot, 0, 2); +-} +- +-/* Hash function for UNSPEC_PROF htab. Use both the caller's name and +- the callee's name (if known). */ +- +-static hashval_t +-unspec_prof_hash (const void *x) +-{ +- const_rtx u = (const_rtx) x; +- const_rtx s1 = XVECEXP (u, 0, 1); +- +- return (htab_hash_string (XSTR (XVECEXP (u, 0, 0), 0)) +- ^ (s1->code == SYMBOL_REF ? htab_hash_string (XSTR (s1, 0)) : 0)); +-} +- +-/* Equality function for UNSPEC_PROF htab. Two pieces of UNSPEC_PROF rtl +- shall refer to the same counter if both caller name and callee rtl +- are identical. */ +- +-static int +-unspec_prof_htab_eq (const void *x, const void *y) +-{ +- const_rtx u0 = (const_rtx) x; +- const_rtx u1 = (const_rtx) y; +- const_rtx s01 = XVECEXP (u0, 0, 1); +- const_rtx s11 = XVECEXP (u1, 0, 1); +- +- return (!strcmp (XSTR (XVECEXP (u0, 0, 0), 0), +- XSTR (XVECEXP (u1, 0, 0), 0)) +- && rtx_equal_p (s01, s11)); +-} +- + /* Conditional execution support. + + This is based on the ARM port but for now is much simpler. +@@ -5563,7 +5472,6 @@ arc_legitimate_constant_p (machine_mode mode, rtx x) + case UNSPEC_TLS_GD: + case UNSPEC_TLS_IE: + case UNSPEC_TLS_OFF: +- case UNSPEC_PROF: + return true; + + default: +@@ -6483,47 +6391,6 @@ arc_is_shortcall_p (rtx sym_ref) + + } + +-/* Emit profiling code for calling CALLEE. Return true if a special +- call pattern needs to be generated. */ +- +-bool +-arc_profile_call (rtx callee) +-{ +- rtx from = XEXP (DECL_RTL (current_function_decl), 0); +- +- if (TARGET_UCB_MCOUNT) +- /* Profiling is done by instrumenting the callee. */ +- return false; +- +- if (CONSTANT_P (callee)) +- { +- rtx count_ptr +- = gen_rtx_CONST (Pmode, +- gen_rtx_UNSPEC (Pmode, +- gen_rtvec (3, from, callee, +- CONST0_RTX (Pmode)), +- UNSPEC_PROF)); +- rtx counter = gen_rtx_MEM (SImode, count_ptr); +- /* ??? The increment would better be done atomically, but as there is +- no proper hardware support, that would be too expensive. */ +- emit_move_insn (counter, +- force_reg (SImode, plus_constant (SImode, counter, 1))); +- return false; +- } +- else +- { +- rtx count_list_ptr +- = gen_rtx_CONST (Pmode, +- gen_rtx_UNSPEC (Pmode, +- gen_rtvec (3, from, CONST0_RTX (Pmode), +- CONST0_RTX (Pmode)), +- UNSPEC_PROF)); +- emit_move_insn (gen_rtx_REG (Pmode, 8), count_list_ptr); +- emit_move_insn (gen_rtx_REG (Pmode, 9), callee); +- return true; +- } +-} +- + /* Worker function for TARGET_RETURN_IN_MEMORY. */ + + static bool +@@ -6670,25 +6537,6 @@ arc_reorg (void) + cfun->machine->arc_reorg_started = 1; + arc_reorg_in_progress = 1; + +- /* Emit special sections for profiling. */ +- if (crtl->profile) +- { +- section *save_text_section; +- rtx_insn *insn; +- int size = get_max_uid () >> 4; +- htab_t htab = htab_create (size, unspec_prof_hash, unspec_prof_htab_eq, +- NULL); +- +- save_text_section = in_section; +- for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) +- if (NONJUMP_INSN_P (insn)) +- walk_stores (PATTERN (insn), write_profile_sections, htab); +- if (htab_elements (htab)) +- in_section = 0; +- switch_to_section (save_text_section); +- htab_delete (htab); +- } +- + /* Link up loop ends with their loop start. */ + { + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index d4cc20ddf708..3df21d416d97 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -121,12 +121,11 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + -X %{mbig-endian:-EB} \ + %{EB} %{EL} \ + %{marclinux*} \ +- %{!marclinux*: %{pg|p|profile:-marclinux_prof;: -marclinux}} \ ++ %{!marclinux*: -marclinux} \ + %{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \ + %{shared:-shared}" + #else +-#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}\ +- %{pg|p:-marcelf_prof;mA7|mARC700|mcpu=arc700|mcpu=ARC700: -marcelf}" ++#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}" + #endif + + #if DEFAULT_LIBC != LIBC_UCLIBC +@@ -135,7 +134,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + #define EXTRA_SPECS \ + { "arc_tls_extra_start_spec", ARC_TLS_EXTRA_START_SPEC }, \ + +-#define STARTFILE_SPEC "%{!shared:crt0.o%s} crti%O%s %{pg|p:crtg.o%s} " \ ++#define STARTFILE_SPEC "%{pg|p:gcrt0.o%s}%{!pg:%{!p:crt0.o%s}} crti%O%s " \ + "%(arc_tls_extra_start_spec) crtbegin.o%s" + #else + #define STARTFILE_SPEC \ +@@ -143,7 +142,7 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + #endif + + #if DEFAULT_LIBC != LIBC_UCLIBC +-#define ENDFILE_SPEC "%{pg|p:crtgend.o%s} crtend.o%s crtn%O%s" ++#define ENDFILE_SPEC "crtend.o%s crtn%O%s" + #else + #define ENDFILE_SPEC \ + LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC) +@@ -154,12 +153,11 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + #define LIB_SPEC \ + "%{pthread:-lpthread} \ + %{shared:-lc} \ +- %{!shared:%{pg|p|profile:-lgmon -u profil --defsym __profil=profil} -lc}" ++ %{!shared:%{profile:-lc_p}%{!profile:-lc}}" + #define TARGET_ASM_FILE_END file_end_indicate_exec_stack + #else + #undef LIB_SPEC +-/* -lc_p not present for arc-elf32-* : ashwin */ +-#define LIB_SPEC "%{!shared:%{g*:-lg} %{pg|p:-lgmon} -lc}" ++#define LIB_SPEC "%{!shared:%{g*:-lg} -lc}" + #endif + + #ifndef DRIVER_ENDIAN_SELF_SPECS +@@ -918,12 +916,14 @@ extern int arc_initial_elimination_offset(int from, int to); + (OFFSET) = arc_initial_elimination_offset ((FROM), (TO)) + + /* Output assembler code to FILE to increment profiler label # LABELNO +- for profiling a function entry. +- We actually emit the profiler code at the call site, so leave this one +- empty. */ +-#define FUNCTION_PROFILER(FILE, LABELNO) \ +- if (TARGET_UCB_MCOUNT) \ +- fprintf (FILE, "\t%s\n", arc_output_libcall ("__mcount")) ++ for profiling a function entry. */ ++#define FUNCTION_PROFILER(FILE, LABELNO) \ ++ do { \ ++ if (flag_pic) \ ++ fprintf (FILE, "\tbl\t__mcount@plt\n"); \ ++ else \ ++ fprintf (FILE, "\tbl\t__mcount\n"); \ ++ } while (0); + + #define NO_PROFILE_COUNTERS 1 + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index cfa55dac5423..d87174a7f321 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -9,7 +9,7 @@ + ;; Saurabh Verma (saurabh.verma@codito.com) + ;; Ramana Radhakrishnan(ramana.radhakrishnan@codito.com) + ;; +-;; Profiling support and performance improvements by ++;; Performance improvements by + ;; Joern Rennecke (joern.rennecke@embecosm.com) + ;; + +@@ -165,9 +165,7 @@ + ]) + + (define_constants +- [(UNSPEC_PROF 18) ; profile callgraph counter +- +- (R0_REG 0) ++ [(R0_REG 0) + (R1_REG 1) + (R2_REG 2) + (R3_REG 3) +@@ -4063,13 +4061,6 @@ + + gcc_assert (MEM_P (operands[0])); + callee = XEXP (operands[0], 0); +- if (crtl->profile && arc_profile_call (callee)) +- { +- emit_call_insn (gen_call_prof (gen_rtx_SYMBOL_REF (Pmode, +- \"_mcount_call\"), +- operands[1])); +- DONE; +- } + /* This is to decide if we should generate indirect calls by loading the + 32 bit address of the callee into a register before performing the + branch and link - this exposes cse opportunities. +@@ -4132,14 +4123,6 @@ + + gcc_assert (MEM_P (operands[1])); + callee = XEXP (operands[1], 0); +- if (crtl->profile && arc_profile_call (callee)) +- { +- emit_call_insn (gen_call_value_prof (operands[0], +- gen_rtx_SYMBOL_REF (Pmode, +- \"_mcount_call\"), +- operands[2])); +- DONE; +- } + /* See the comment in define_expand \"call\". */ + if (GET_CODE (callee) != REG + && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee))) +@@ -4622,13 +4605,6 @@ + + if (operands[2] == NULL_RTX) + operands[2] = const0_rtx; +- if (crtl->profile && arc_profile_call (callee)) +- { +- emit_insn (gen_sibcall_prof +- (gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"), +- operands[1], operands[2])); +- DONE; +- } + if (GET_CODE (callee) != REG + && (GET_CODE (callee) == PLUS || arc_is_longcall_p (callee))) + XEXP (operands[0], 0) = force_reg (Pmode, callee); +@@ -4648,13 +4624,6 @@ + + if (operands[3] == NULL_RTX) + operands[3] = const0_rtx; +- if (crtl->profile && arc_profile_call (XEXP (operands[1], 0))) +- { +- emit_insn (gen_sibcall_value_prof +- (operands[0], gen_rtx_SYMBOL_REF (Pmode, \"_mcount_call\"), +- operands[2], operands[3])); +- DONE; +- } + if (GET_CODE (callee) != REG && arc_is_longcall_p (callee)) + XEXP (operands[1], 0) = force_reg (Pmode, callee); + }" +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 15785498b34e..d8b26102d469 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -346,10 +346,6 @@ mlra-priority-noncompact + Target RejectNegative Var(arc_lra_prioritytag, ARC_LRA_PRIORITY_NONCOMPACT) + Reduce priority for r0..r3 / r12..r15 with TARGET_REGISTER_PRIORITY. + +-mucb-mcount +-Target Report Var(TARGET_UCB_MCOUNT) +-instrument with mcount calls as in the ucb code. +- + ; backward-compatibility aliases, translated by DRIVER_SELF_SPECS + + mEA +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index a3fa950d064b..c4d574660c1a 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -592,7 +592,7 @@ Objective-C and Objective-C++ Dialects}. + -mcrc -mdsp-packa -mdvbf -mlock -mmac-d16 -mmac-24 -mrtsc -mswape @gol + -mtelephony -mxy -misize -mannotate-align -marclinux -marclinux_prof @gol + -mlong-calls -mmedium-calls -msdata @gol +--mucb-mcount -mvolatile-cache -mtp-regno=@var{regno} @gol ++-mvolatile-cache -mtp-regno=@var{regno} @gol + -malign-call -mauto-modify-reg -mbbit-peephole -mno-brcc @gol + -mcase-vector-pcrel -mcompact-casesi -mno-cond-exec -mearly-cbranchsi @gol + -mexpand-adddi -mindexed-loads -mlra -mlra-priority-none @gol +@@ -13658,12 +13658,6 @@ Do not generate sdata references. This is the default for tool chains + built for @w{@code{arc-linux-uclibc}} and @w{@code{arceb-linux-uclibc}} + targets. + +-@item -mucb-mcount +-@opindex mucb-mcount +-Instrument with mcount calls as used in UCB code. I.e. do the +-counting in the callee, not the caller. By default ARC instrumentation +-counts in the caller. +- + @item -mvolatile-cache + @opindex mvolatile-cache + Use ordinarily cached memory accesses for volatile references. This is the +diff --git a/libgcc/config.host b/libgcc/config.host +index 5102eee42931..035d38d03713 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -365,13 +365,13 @@ alpha*-dec-*vms*) + md_unwind_header=alpha/vms-unwind.h + ;; + arc*-*-elf*) +- tmake_file="arc/t-arc-newlib arc/t-arc" +- extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o libgmon.a crtg.o crtgend.o" +- extra_parts="${extra_parts} crttls.o" ++ tmake_file="arc/t-arc" ++ extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o" ++ extra_parts="$extra_parts crttls.o" + ;; + arc*-*-linux-uclibc*) +- tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc700-uClibc arc/t-arc" +- extra_parts="$extra_parts crti.o crtn.o libgmon.a crtg.o crtgend.o" ++ tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc-uClibc arc/t-arc" ++ extra_parts="$extra_parts crti.o crtn.o" + extra_parts="$extra_parts crttls.o" + ;; + arm-wrs-vxworks) +diff --git a/libgcc/config/arc/crtg.S b/libgcc/config/arc/crtg.S +deleted file mode 100644 +index ca3cfb6a9cbe..000000000000 +--- a/libgcc/config/arc/crtg.S ++++ /dev/null +@@ -1,51 +0,0 @@ +-/* Code to start and stop profiling for the Synopsys DesignWare ARC CPU. +- +- Copyright (C) 1994-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +- .section .init +- .global _init +- .global _fini +- .global __monstartup +- mov_s r0,_init +- mov_s r1,_fini +- jl __monstartup +- +- .section .__arc_profile_desc, "a" +- .global __arc_profile_desc_secstart +- .balign 4 +-__arc_profile_desc_secstart: +- .section .__arc_profile_forward, "a" +- .global __arc_profile_forward_secstart +- .balign 4 +-__arc_profile_forward_secstart: +- .section .__arc_profile_counters, "aw" +- .global __arc_profile_counters_secstart +- .balign 4 +-__arc_profile_counters_secstart: +- +- .section .fini +- .global _mcleanup +- jl _mcleanup +diff --git a/libgcc/config/arc/crtgend.S b/libgcc/config/arc/crtgend.S +deleted file mode 100644 +index fad630f139e5..000000000000 +--- a/libgcc/config/arc/crtgend.S ++++ /dev/null +@@ -1,33 +0,0 @@ +-/* Code to start and stop profiling for the Synopsys DesignWare ARC CPU. +- +- Copyright (C) 1994-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +- .section .__arc_profile_desc, "a" +- .global __arc_profile_desc_secend +-__arc_profile_desc_secend: +- .section .__arc_profile_forward, "a" +- .global __arc_profile_forward_secend +-__arc_profile_forward_secend: +diff --git a/libgcc/config/arc/gmon/atomic.h b/libgcc/config/arc/gmon/atomic.h +deleted file mode 100644 +index 049aa523b5b9..000000000000 +--- a/libgcc/config/arc/gmon/atomic.h ++++ /dev/null +@@ -1,26 +0,0 @@ +-/* Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-/* File deliberately left blank. */ +diff --git a/libgcc/config/arc/gmon/auxreg.h b/libgcc/config/arc/gmon/auxreg.h +deleted file mode 100644 +index 5210ea02ccc8..000000000000 +--- a/libgcc/config/arc/gmon/auxreg.h ++++ /dev/null +@@ -1,35 +0,0 @@ +-/* Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#define LP_START 0x02 +-#define LP_END 0x03 +-#define IDENTITY 0x04 +-#define STATUS32 0x0a +-#define COUNT0 0x21 /* Timer 0 count */ +-#define CONTROL0 0x22 /* Timer 0 control */ +-#define LIMIT0 0x23 /* Timer 0 limit */ +-#define INT_VECTOR_BASE 0x25 +-#define D_CACHE_BUILD 0x72 +-#define DC_FLDL 0x4c +diff --git a/libgcc/config/arc/gmon/dcache_linesz.S b/libgcc/config/arc/gmon/dcache_linesz.S +deleted file mode 100644 +index 29572aefc8e9..000000000000 +--- a/libgcc/config/arc/gmon/dcache_linesz.S ++++ /dev/null +@@ -1,57 +0,0 @@ +-/* This file contains code to do profiling. +- +- Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#include "../asm.h" +-#include "auxreg.h" +-/* This file contains code to do profiling. */ +- .weak __profile_timer_cycles +- .global __profile_timer_cycles +- .set __profile_timer_cycles, 200 +- .text +- ; For Arctangent-A5, if no data cache is present, a read of the +- ; cache build register returns the ID register. For ARC600 and +- ; later, the version field will be zero. +- .global __dcache_linesz +- .balign 4 +-__dcache_linesz: +-#if !defined (__EM__) && !defined (__HS__) +- lr r12,[D_CACHE_BUILD] +- extb_s r0,r12 +- breq_s r0,0,.Lsz_nocache +- brge r0,0x20,.Lsz_havecache +- lr r0,[IDENTITY] +- breq r12,r0,.Lsz_nocache +-.Lsz_havecache: +- lsr_s r12,r12,16 +- mov_s r0,16 +- bmsk_s r12,r12,3 +- asl_s r0,r0,r12 +- j_s [blink] +-.Lsz_nocache: +-#endif /* !__EM__ && !__HS__ */ +- mov_s r0,1 +- j_s [blink] +diff --git a/libgcc/config/arc/gmon/gmon.c b/libgcc/config/arc/gmon/gmon.c +deleted file mode 100644 +index 82c09b0a1a2d..000000000000 +--- a/libgcc/config/arc/gmon/gmon.c ++++ /dev/null +@@ -1,450 +0,0 @@ +-/*- +- * Copyright (c) 1983, 1992, 1993 +- * The Regents of the University of California. All rights reserved. +- * Copyright (C) 2007-2016 Free Software Foundation, Inc. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- */ +-#if 0 +-#include +-#include +-#endif +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#if 0 +-#include +-#include +- +-#ifdef USE_IN_LIBIO +-# include +-#endif +-#endif +-#define internal_function +-#define weak_alias(fun,aliasid) extern __typeof(fun) aliasid __attribute__ ((weak, alias (#fun))); +-#define __libc_enable_secure 0 +- +-/* Head of basic-block list or NULL. */ +-struct __bb *__bb_head attribute_hidden; +- +-struct gmonparam _gmonparam attribute_hidden = { GMON_PROF_OFF }; +- +-/* +- * See profil(2) where this is described: +- */ +-static int s_scale; +-#define SCALE_1_TO_1 0x10000L +- +-#define ERR(s) write (STDERR_FILENO, s, sizeof (s) - 1) +- +-void moncontrol (int mode); +-void __moncontrol (int mode); +-static void write_hist (int fd) internal_function; +-static void write_call_graph (int fd) internal_function; +-static void write_bb_counts (int fd) internal_function; +- +-/* +- * Control profiling +- * profiling is what mcount checks to see if +- * all the data structures are ready. +- */ +-void +-__moncontrol (int mode) +-{ +- struct gmonparam *p = &_gmonparam; +- +- /* Don't change the state if we ran into an error. */ +- if (p->state == GMON_PROF_ERROR) +- return; +- +- if (mode) +- { +- /* start */ +- __profil((void *) p->kcount, p->kcountsize, p->lowpc, s_scale); +- p->state = GMON_PROF_ON; +- } +- else +- { +- /* stop */ +- __profil(NULL, 0, 0, 0); +- p->state = GMON_PROF_OFF; +- } +-} +-weak_alias (__moncontrol, moncontrol) +- +- +-void +-__monstartup (u_long lowpc, u_long highpc) +-{ +- register int o; +- char *cp; +- struct gmonparam *p = &_gmonparam; +- int linesz; +- +- /* +- * round lowpc and highpc to multiples of the density we're using +- * so the rest of the scaling (here and in gprof) stays in ints. +- */ +- p->lowpc = ROUNDDOWN(lowpc, HISTFRACTION * sizeof(HISTCOUNTER)); +- if (sizeof *p->froms % sizeof(HISTCOUNTER) != 0) +- { +- p->highpc = ROUNDUP(highpc, HISTFRACTION * sizeof(HISTCOUNTER)); +- p->textsize = p->highpc - p->lowpc; +- p->kcountsize = ROUNDUP((p->textsize + HISTFRACTION - 1) / HISTFRACTION, +- sizeof (*p->froms)); +- } +- else +- { +- /* Avoid odd scales by rounding up highpc to get kcountsize rounded. */ +- p->textsize = ROUNDUP (highpc - p->lowpc, +- HISTFRACTION * sizeof (*p->froms)); +- p->highpc = p->lowpc + p->textsize; +- p->kcountsize = p->textsize / HISTFRACTION; +- } +- p->hashfraction = HASHFRACTION; +- p->log_hashfraction = -1; +- /* The following test must be kept in sync with the corresponding +- test in mcount.c. */ +- if ((HASHFRACTION & (HASHFRACTION - 1)) == 0) { +- /* if HASHFRACTION is a power of two, mcount can use shifting +- instead of integer division. Precompute shift amount. */ +- p->log_hashfraction = ffs(p->hashfraction * sizeof(*p->froms)) - 1; +- } +- p->tolimit = p->textsize * ARCDENSITY / 100; +- if (p->tolimit < MINARCS) +- p->tolimit = MINARCS; +- else if (p->tolimit > MAXARCS) +- p->tolimit = MAXARCS; +- p->tossize = p->tolimit * sizeof(struct tostruct); +- +- /* p->kcount must not share cache lines with the adjacent data, because +- we use uncached accesses while profiling. */ +- linesz = __dcache_linesz (); +- cp = calloc (ROUNDUP (p->kcountsize, linesz) + p->tossize +- + (linesz - 1), 1); +- if (! cp) +- { +- ERR("monstartup: out of memory\n"); +- p->tos = NULL; +- p->state = GMON_PROF_ERROR; +- /* In case we loose the error state due to a race, +- prevent invalid writes also by clearing tolimit. */ +- p->tolimit = 0; +- return; +- } +- p->tos = (struct tostruct *)cp; +- cp += p->tossize; +- cp = (char *) ROUNDUP ((ptrdiff_t) cp, linesz); +- p->kcount = (HISTCOUNTER *)cp; +- cp += ROUNDUP (p->kcountsize, linesz); +- +- p->tos[0].link = 0; +- +- o = p->highpc - p->lowpc; +- if (p->kcountsize < (u_long) o) +- { +-#ifndef hp300 +- s_scale = ((float)p->kcountsize / o ) * SCALE_1_TO_1; +-#else +- /* avoid floating point operations */ +- int quot = o / p->kcountsize; +- +- if (quot >= 0x10000) +- s_scale = 1; +- else if (quot >= 0x100) +- s_scale = 0x10000 / quot; +- else if (o >= 0x800000) +- s_scale = 0x1000000 / (o / (p->kcountsize >> 8)); +- else +- s_scale = 0x1000000 / ((o << 8) / p->kcountsize); +-#endif +- } else +- s_scale = SCALE_1_TO_1; +- +- __moncontrol(1); +-} +-weak_alias (__monstartup, monstartup) +- +- +-static void +-internal_function +-write_hist (int fd) +-{ +- u_char tag = GMON_TAG_TIME_HIST; +- struct arc_gmon_hist_hdr thdr __attribute__ ((aligned (__alignof__ (char *)))); +- int r; +- +- if (_gmonparam.kcountsize > 0) +- { +- *(char **) thdr.low_pc = (char *) _gmonparam.lowpc; +- *(char **) thdr.high_pc = (char *) _gmonparam.highpc; +- *(int32_t *) thdr.hist_size = (_gmonparam.kcountsize +- / sizeof (HISTCOUNTER)); +- *(int32_t *) thdr.prof_rate = __profile_frequency (); +- strncpy (thdr.dimen, "seconds", sizeof (thdr.dimen)); +- thdr.dimen_abbrev = 's'; +- +- r = write (fd, &tag, sizeof tag); +- if (r != sizeof tag) +- return; +- r = write (fd, &thdr, sizeof thdr); +- if (r != sizeof thdr) +- return; +- r = write (fd,_gmonparam.kcount, _gmonparam.kcountsize); +- if ((unsigned) r != _gmonparam.kcountsize) +- return; +- } +-} +- +- +-static void +-internal_function +-write_call_graph (int fd) +-{ +-#define NARCS_PER_WRITE 64 +-#define BYTES_PER_ARC (1 + sizeof (struct gmon_cg_arc_record)) +-#define BYTES_PER_WRITE (BYTES_PER_ARC * NARCS_PER_WRITE) +- ARCINDEX to_index; +- u_long frompc, selfpc, count; +- char buffer[BYTES_PER_WRITE], *p; +- u_long *prof_desc = __arc_profile_desc_secstart; +- u_long *prof_count = __arc_profile_counters_secstart; +- u_long *prof_desc_end = __arc_profile_desc_secend; +- u_long *prof_forward = __arc_profile_forward_secstart; +- +- for (p = buffer; p < buffer + BYTES_PER_WRITE; p += BYTES_PER_ARC) +- *p = GMON_TAG_CG_ARC; +- p = buffer; +- frompc = *prof_desc++ & -2; +- while (prof_desc < prof_desc_end) +- { +- selfpc = *prof_desc++; +- if (selfpc & 1) +- { +- frompc = selfpc & -2; +- selfpc = *prof_desc++; +- } +- count = *prof_count++; +- if (selfpc) +- { +- struct arc +- { +- char *frompc; +- char *selfpc; +- int32_t count; +- } +- arc; +- +- if (!count) +- continue; +- arc.frompc = (char *) frompc; +- arc.selfpc = (char *) selfpc; +- arc.count = count; +- memcpy (p + 1, &arc, sizeof arc); +- p += 1 + sizeof arc; +- +- if (p == buffer + BYTES_PER_WRITE) +- { +- write (fd, buffer, BYTES_PER_WRITE); +- p = buffer; +- } +- } +- else +- { +- for (to_index = count; +- to_index != 0; +- to_index = _gmonparam.tos[to_index].link) +- { +- struct arc +- { +- char *frompc; +- char *selfpc; +- int32_t count; +- } +- arc; +- +- arc.frompc = (char *) frompc; +- arc.selfpc = (char *) _gmonparam.tos[to_index].selfpc; +- arc.count = _gmonparam.tos[to_index].count; +- memcpy (p + 1, &arc, sizeof arc); +- p += 1 + sizeof arc; +- +- if (p == buffer + BYTES_PER_WRITE) +- { +- write (fd, buffer, BYTES_PER_WRITE); +- p = buffer; +- } +- } +- } +- } +- while (prof_forward < __arc_profile_forward_secend) +- { +- /* ??? The 'call count' is actually supposed to be a fixed point +- factor, with 16 bits each before and after the point. +- It would be much nicer if we figured out the actual number +- of calls to the caller, and multiplied that with the fixed point +- factor to arrive at the estimated calls for the callee. */ +- memcpy (p + 1, prof_forward, 3 * sizeof *prof_forward); +- prof_forward += 3; +- p += 1 + 3 * sizeof *prof_forward; +- if (p == buffer + BYTES_PER_WRITE) +- { +- write (fd, buffer, BYTES_PER_WRITE); +- p = buffer; +- } +- } +- if (p != buffer) +- write (fd, buffer, p - buffer); +-} +- +- +-static void +-internal_function +-write_bb_counts (int fd) +-{ +- struct __bb *grp; +- u_char tag = GMON_TAG_BB_COUNT; +- size_t ncounts; +- size_t i; +- +- struct { unsigned long address; long count; } bbbody[8]; +- size_t nfilled; +- +- /* Write each group of basic-block info (all basic-blocks in a +- compilation unit form a single group). */ +- +- for (grp = __bb_head; grp; grp = grp->next) +- { +- ncounts = grp->ncounts; +- write (fd, &tag, 1); +- write (fd, &ncounts, sizeof ncounts); +- for (nfilled = i = 0; i < ncounts; ++i) +- { +- if (nfilled == sizeof (bbbody) / sizeof (bbbody[0])) +- { +- write (fd, bbbody, sizeof bbbody); +- nfilled = 0; +- } +- +- bbbody[nfilled].address = grp->addresses[i]; +- bbbody[nfilled++].count = grp->counts[i]; +- } +- if (nfilled > 0) +- write (fd, bbbody, nfilled * sizeof bbbody[0]); +- } +-} +- +- +-static void +-write_gmon (void) +-{ +- struct gmon_hdr ghdr __attribute__ ((aligned (__alignof__ (int)))); +- int fd = -1; +- char *env; +- +-#ifndef O_NOFOLLOW +-# define O_NOFOLLOW 0 +-#endif +- +- env = getenv ("GMON_OUT_PREFIX"); +- if (env != NULL && !__libc_enable_secure) +- { +- size_t len = strlen (env); +- char buf[len + 20]; +- snprintf (buf, sizeof (buf), "%s.%u", env, getpid ()); +- fd = open (buf, O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW, 0666); +- } +- +- if (fd == -1) +- { +- fd = open ("gmon.out", O_CREAT|O_TRUNC|O_WRONLY|O_NOFOLLOW, +- 0666); +- if (fd < 0) +- { +- perror ("_mcleanup: gmon.out"); +- return; +- } +- } +- +- /* write gmon.out header: */ +- memset (&ghdr, '\0', sizeof (struct gmon_hdr)); +- memcpy (&ghdr.cookie[0], GMON_MAGIC, sizeof (ghdr.cookie)); +- *(int32_t *) ghdr.version = GMON_VERSION; +- write (fd, &ghdr, sizeof (struct gmon_hdr)); +- +- /* write PC histogram: */ +- write_hist (fd); +- +- /* write call-graph: */ +- write_call_graph (fd); +- +- /* write basic-block execution counts: */ +- write_bb_counts (fd); +- +- close (fd); +-} +- +- +-void +-__write_profiling (void) +-{ +- int save = _gmonparam.state; +- _gmonparam.state = GMON_PROF_OFF; +- if (save == GMON_PROF_ON) +- write_gmon (); +- _gmonparam.state = save; +-} +-#ifndef SHARED +-/* This symbol isn't used anywhere in the DSO and it is not exported. +- This would normally mean it should be removed to get the same API +- in static libraries. But since profiling is special in static libs +- anyway we keep it. But not when building the DSO since some +- quality assurance tests will otherwise trigger. */ +-weak_alias (__write_profiling, write_profiling) +-#endif +- +- +-void +-_mcleanup (void) +-{ +- __moncontrol (0); +- +- if (_gmonparam.state != GMON_PROF_ERROR) +- write_gmon (); +- +- /* free the memory. */ +- if (_gmonparam.tos != NULL) +- free (_gmonparam.tos); +-} +diff --git a/libgcc/config/arc/gmon/machine-gmon.h b/libgcc/config/arc/gmon/machine-gmon.h +deleted file mode 100644 +index e7549aedb7cf..000000000000 +--- a/libgcc/config/arc/gmon/machine-gmon.h ++++ /dev/null +@@ -1,65 +0,0 @@ +-/* Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#ifndef MACHINE_GMON_H +-#define MACHINE_GMON_H +- +-/* We can't fake out own header because the newlib / uclibc +- headers in GCC_FOR_TARGET take precedence. */ +- +-#define __BEGIN_DECLS +-#define __END_DECLS +- +-#define __THROW +- +-extern int __dcache_linesz (void); +- +-#define _MCOUNT_DECL(countp, selfpc) \ +- static inline void _mcount_internal (void *countp, u_long selfpc) +- +-extern void _mcount (void); +-extern void _mcount_call (void); +- +-/* N.B.: the calling point might be a sibcall, thus blink does not necessarily +- hold the caller's address. r8 doesn't hold the caller's address, either, +- but rather a pointer to the counter data structure associated with the +- caller. +- This function must be compiled with optimization turned on in order to +- enable a sibcall for the final call to selfpc; this is important when trying +- to profile a program with deep tail-recursion that would get a stack +- overflow otherwise. */ +-#define MCOUNT \ +-void \ +-_mcount_call (void) \ +-{ \ +- register void *countp __asm("r8"); \ +- register u_long selfpc __asm("r9"); \ +- _mcount_internal (countp, selfpc); \ +- ((void (*)(void)) selfpc) (); \ +-} +- +-extern int __profil (u_short *,size_t, size_t, u_int); +- +-#endif /* MACHINE_GMON_H */ +diff --git a/libgcc/config/arc/gmon/mcount.c b/libgcc/config/arc/gmon/mcount.c +deleted file mode 100644 +index 8afca36b88c9..000000000000 +--- a/libgcc/config/arc/gmon/mcount.c ++++ /dev/null +@@ -1,206 +0,0 @@ +-/*- +- * Copyright (c) 1983, 1992, 1993 +- * The Regents of the University of California. All rights reserved. +- * +- * Copyright (C) 2007-2016 Free Software Foundation, Inc. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- */ +- +-#if !defined(lint) && !defined(KERNEL) && defined(LIBC_SCCS) +-static char sccsid[] = "@(#)mcount.c 8.1 (Berkeley) 6/4/93"; +-#endif +- +-#if 0 +-#include +-#include +-#endif +-#include +- +-/* This file provides the machine-dependent definitions of the _MCOUNT_DECL +- and MCOUNT macros. */ +-#include +- +-#include +- +-/* +- * mcount is called on entry to each function compiled with the profiling +- * switch set. _mcount(), which is declared in a machine-dependent way +- * with _MCOUNT_DECL, does the actual work and is either inlined into a +- * C routine or called by an assembly stub. In any case, this magic is +- * taken care of by the MCOUNT definition in . +- * +- * _mcount updates data structures that represent traversals of the +- * program's call graph edges. frompc and selfpc are the return +- * address and function address that represents the given call graph edge. +- * +- * Note: the original BSD code used the same variable (frompcindex) for +- * both frompcindex and frompc. Any reasonable, modern compiler will +- * perform this optimization. +- */ +-_MCOUNT_DECL(count_ptr, selfpc) /* _mcount; may be static, inline, etc */ +-{ +- register ARCINDEX *frompcindex; +- register struct tostruct *top, *prevtop; +- register struct gmonparam *p; +- register ARCINDEX toindex; +- +- /* Check for nested function trampoline. */ +- if (selfpc & 2) +- selfpc = *(u_long *) (selfpc + 10); +- +- p = &_gmonparam; +- /* +- * check that we are profiling +- * and that we aren't recursively invoked. +- */ +-#if 0 +- if (catomic_compare_and_exchange_bool_acq (&p->state, GMON_PROF_BUSY, +- GMON_PROF_ON)) +- return; +-#elif defined (__ARC700__) +-/* ??? This could temporarily lose the ERROR / OFF condition in a race, +- but doing an actual compare_and_exchange would be too costly. It would +- be better if we had a semaphore independent of the 'sticky' state, but +- then we could run into ABI compatibility problems with the size of struct +- gmonparam. */ +- { +- u_long old_state; +- +- __asm ("ex %0,%1": "=r" (old_state), "+m" (p->state) +- : "0" (GMON_PROF_BUSY)); +- if (old_state != GMON_PROF_ON) +- { +- switch (old_state) +- { +- case GMON_PROF_OFF: +- __asm ("ex %0,%1": "+r" (old_state), "+m" (p->state)); +- if (old_state == GMON_PROF_BUSY +- /* Switching off while we say we are busy while profiling +- was actually already switched off is all right. */ +- || old_state == GMON_PROF_OFF) +- break; +- /* It is not clear if we should allow switching on +- profiling at this point, and how to handle further races. +- For now, record an error in this case. */ +- /* Fall through. */ +- default: /* We expect here only GMON_PROF_ERROR. */ +- p->state = GMON_PROF_ERROR; +- break; +- case GMON_PROF_BUSY: break; +- } +- return; +- } +- } +-#else /* ??? No semaphore primitives available. */ +- if (p->state != GMON_PROF_ON) +- return; +- p->state = GMON_PROF_BUSY; +-#endif +- +- frompcindex = count_ptr; +- toindex = *frompcindex; +- if (toindex == 0) { +- /* +- * first time traversing this arc +- */ +- toindex = ++p->tos[0].link; +- if (toindex >= (ARCINDEX) p->tolimit) +- /* halt further profiling */ +- goto overflow; +- +- *frompcindex = toindex; +- top = &p->tos[toindex]; +- top->selfpc = selfpc; +- top->count = 1; +- top->link = 0; +- goto done; +- } +- top = &p->tos[toindex]; +- if (top->selfpc == selfpc) { +- /* +- * arc at front of chain; usual case. +- */ +- top->count++; +- goto done; +- } +- /* +- * have to go looking down chain for it. +- * top points to what we are looking at, +- * prevtop points to previous top. +- * we know it is not at the head of the chain. +- */ +- for (; /* goto done */; ) { +- if (top->link == 0) { +- /* +- * top is end of the chain and none of the chain +- * had top->selfpc == selfpc. +- * so we allocate a new tostruct +- * and link it to the head of the chain. +- */ +- toindex = ++p->tos[0].link; +- if (toindex >= (ARCINDEX) p->tolimit) +- goto overflow; +- +- top = &p->tos[toindex]; +- top->selfpc = selfpc; +- top->count = 1; +- top->link = *frompcindex; +- *frompcindex = toindex; +- goto done; +- } +- /* +- * otherwise, check the next arc on the chain. +- */ +- prevtop = top; +- top = &p->tos[top->link]; +- if (top->selfpc == selfpc) { +- /* +- * there it is. +- * increment its count +- * move it to the head of the chain. +- */ +- top->count++; +- toindex = prevtop->link; +- prevtop->link = top->link; +- top->link = *frompcindex; +- *frompcindex = toindex; +- goto done; +- } +- +- } +-done: +- p->state = GMON_PROF_ON; +- return; +-overflow: +- p->state = GMON_PROF_ERROR; +- return; +-} +- +-/* +- * Actual definition of mcount function. Defined in , +- * which is included by . +- */ +-MCOUNT +diff --git a/libgcc/config/arc/gmon/prof-freq-stub.S b/libgcc/config/arc/gmon/prof-freq-stub.S +deleted file mode 100644 +index 9ffb30b9736d..000000000000 +--- a/libgcc/config/arc/gmon/prof-freq-stub.S ++++ /dev/null +@@ -1,40 +0,0 @@ +-/* This file contains code to do profiling. +- +- Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#include "../asm.h" +-/* This file contains code to do profiling. */ +- .weak __profile_frequency_value +- .global __profile_frequency_value +- .set __profile_frequency_value, 1000 +- .text +- .balign 4 +- .global __profile_frequency +- FUNC(__profile_frequency) +-__profile_frequency: +- mov_s r0,__profile_frequency_value +- j_s [blink] +- ENDFUNC(__profile_frequency) +diff --git a/libgcc/config/arc/gmon/prof-freq.c b/libgcc/config/arc/gmon/prof-freq.c +deleted file mode 100644 +index 4437a37d80a8..000000000000 +--- a/libgcc/config/arc/gmon/prof-freq.c ++++ /dev/null +@@ -1,60 +0,0 @@ +-/* Return frequency of ticks reported by profil. Generic version. */ +-/*- +- * Copyright (c) 1983, 1992, 1993 +- * The Regents of the University of California. All rights reserved. +- * +- * Copyright (C) 2007-2016 Free Software Foundation, Inc. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- */ +- +- +-#include +-#include +-#if 0 +-#include +-#else +-#include "sys/gmon.h" +-#endif +- +-int +-__profile_frequency (void) +-{ +- /* +- * Discover the tick frequency of the machine if something goes wrong, +- * we return 0, an impossible hertz. +- */ +- struct itimerval tim; +- +- tim.it_interval.tv_sec = 0; +- tim.it_interval.tv_usec = 1; +- tim.it_value.tv_sec = 0; +- tim.it_value.tv_usec = 0; +- setitimer(ITIMER_REAL, &tim, 0); +- setitimer(ITIMER_REAL, 0, &tim); +- if (tim.it_interval.tv_usec < 2) +- return 0; +- return (1000000 / tim.it_interval.tv_usec); +-} +diff --git a/libgcc/config/arc/gmon/profil.S b/libgcc/config/arc/gmon/profil.S +deleted file mode 100644 +index 807e9fe60cc7..000000000000 +--- a/libgcc/config/arc/gmon/profil.S ++++ /dev/null +@@ -1,164 +0,0 @@ +-/* This file contains code to do profiling. +- +- Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#include "../asm.h" +-#include "auxreg.h" +-/* This file contains code to do profiling. */ +- .weak __profile_timer_cycles +- .global __profile_timer_cycles +- .set __profile_timer_cycles, 200 +- +- .section .bss +- .global __profil_offset +- .align 4 +- .type __profil_offset, @object +- .size __profil_offset, 4 +-__profil_offset: +- .zero 4 +- +- .text +- .global __dcache_linesz +- .global __profil +- FUNC(__profil) +-#if !defined (__EM__) && !defined (__HS__) +-.Lstop_profiling: +- sr r0,[CONTROL0] +- j_s [blink] +- .balign 4 +-__profil: +-.Lprofil: +- breq_s r0,0,.Lstop_profiling +- ; r0: buf r1: bufsiz r2: offset r3: scale +- bxor.f r3,r3,15; scale must be 0x8000, i.e. 1/2; generate 0. +- push_s blink +- lsr_s r2,r2,1 +- mov_s r8,r0 +- flag.ne 1 ; halt if wrong scale +- sub_s r0,r0,r2 +- st r0,[__profil_offset] +- bl __dcache_linesz +- pop_s blink +- bbit1.d r0,0,nocache +- mov_s r0,r8 +-#ifdef __ARC700__ +- add_s r1,r1,31 +- lsr.f lp_count,r1,5 +- lpne 2f +- sr r0,[DC_FLDL] +- add_s r0,r0,32 +-#else /* !__ARC700__ */ +-# FIX ME: set up loop according to cache line size +- lr r12,[D_CACHE_BUILD] +- sub_s r0,r0,16 +- sub_s r1,r1,1 +- lsr_s r12,r12,16 +- asr_s r1,r1,4 +- bmsk_s r12,r12,3 +- asr_s r1,r1,r12 +- add.f lp_count,r1,1 +- mov_s r1,16 +- asl_s r1,r1,r12 +- lpne 2f +- add r0,r0,r1 +- sr r0,[DC_FLDL] +-#endif /* __ARC700__ */ +-2: b_s .Lcounters_cleared +-nocache: +-.Lcounters_cleared: +- lr r1,[INT_VECTOR_BASE] ; disable timer0 interrupts +- sr r3,[CONTROL0] +- sr r3,[COUNT0] +-0: ld_s r0,[pcl,1f-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF +-0: ld_s r12,[pcl,1f+4-0b+((0b-.Lprofil) & 2)] ; 1f@GOTOFF + 4 +- st_s r0,[r1,24]; timer0 uses vector3 +- st_s r12,[r1,24+4]; timer0 uses vector3 +- ;sr 10000,[LIMIT0] +- sr __profile_timer_cycles,[LIMIT0] +- mov_s r12,3 ; enable timer interrupts; count only when not halted. +- sr r12,[CONTROL0] +- lr r12,[STATUS32] +- bset_s r12,r12,1 ; allow level 1 interrupts +- flag r12 +- mov_s r0,0 +- j_s [blink] +- .balign 4 +-1: j __profil_irq +-#else +-__profil: +- .balign 4 +- mov_s r0,-1 +- j_s [blink] +-#endif /* !__EM__ && !__HS__ */ +- ENDFUNC(__profil) +- +- FUNC(__profil_irq) +- .balign 4 ; make final jump unaligned to avoid delay penalty +- .balign 32,0,12 ; make sure the code spans no more that two cache lines +- nop_s +-__profil_irq: +-#if !defined (__EM__) && !defined (__HS__) +- push_s r0 +- ld r0,[__profil_offset] +- push_s r1 +- lsr r1,ilink1,2 +- push_s r2 +- ldw.as.di r2,[r0,r1] +- add1 r0,r0,r1 +- ld_s r1,[sp,4] +- add_s r2,r2,1 +- bbit1 r2,16,nostore +- stw.di r2,[r0] +-nostore:ld.ab r2,[sp,8] +- pop_s r0 +- j.f [ilink1] +-#else +- rtie +-#endif /* !__EM__ && !__HS__ */ +- ENDFUNC(__profil_irq) +- +-; could save one cycle if the counters were allocated at link time and +-; the contents of __profil_offset were pre-computed at link time, like this: +-#if 0 +-; __profil_offset needs to be PROVIDEd as __profile_base-text/4 +- .global __profil_offset +- .balign 4 +-__profil_irq: +- push_s r0 +- lsr r0,ilink1,2 +- add1 r0,__profil_offset,r0 +- push_s r1 +- ldw.di r1,[r0] +- +- +- add_s r1,r1,1 +- bbit1 r1,16,nostore +- stw.di r1,[r0] +-nostore:pop_s r1 +- pop_s r0 +- j [ilink1] +-#endif /* 0 */ +diff --git a/libgcc/config/arc/gmon/sys/gmon.h b/libgcc/config/arc/gmon/sys/gmon.h +deleted file mode 100644 +index f17165a3a823..000000000000 +--- a/libgcc/config/arc/gmon/sys/gmon.h ++++ /dev/null +@@ -1,217 +0,0 @@ +-/*- +- * Copyright (c) 1982, 1986, 1992, 1993 +- * The Regents of the University of California. All rights reserved. +- * Copyright (C) 2007-2016 Free Software Foundation, Inc. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions and the following disclaimer. +- * 2. Redistributions in binary form must reproduce the above copyright +- * notice, this list of conditions and the following disclaimer in the +- * documentation and/or other materials provided with the distribution. +- * 4. Neither the name of the University nor the names of its contributors +- * may be used to endorse or promote products derived from this software +- * without specific prior written permission. +- * +- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +- * SUCH DAMAGE. +- * +- * @(#)gmon.h 8.2 (Berkeley) 1/4/94 +- */ +- +-#ifndef _SYS_GMON_H +-#define _SYS_GMON_H 1 +- +-#if 0 +-#include +-#include +-#else +-#include +-#include "machine-gmon.h" +-#define attribute_hidden __attribute__ ((visibility("hidden"))) +-#endif +- +-#include +- +-/* +- * See gmon_out.h for gmon.out format. +- */ +- +-/* structure emitted by "gcc -a". This must match struct bb in +- gcc/libgcc2.c. It is OK for gcc to declare a longer structure as +- long as the members below are present. */ +-struct __bb +-{ +- long zero_word; +- const char *filename; +- long *counts; +- long ncounts; +- struct __bb *next; +- const unsigned long *addresses; +-}; +- +-extern struct __bb *__bb_head; +- +-/* +- * histogram counters are unsigned shorts (according to the kernel). +- */ +-#define HISTCOUNTER unsigned short +- +-/* +- * fraction of text space to allocate for histogram counters here, 1/2 +- */ +-#define HISTFRACTION 2 +- +-/* +- * Fraction of text space to allocate for from hash buckets. +- * The value of HASHFRACTION is based on the minimum number of bytes +- * of separation between two subroutine call points in the object code. +- * Given MIN_SUBR_SEPARATION bytes of separation the value of +- * HASHFRACTION is calculated as: +- * +- * HASHFRACTION = MIN_SUBR_SEPARATION / (2 * sizeof(short) - 1); +- * +- * For example, on the VAX, the shortest two call sequence is: +- * +- * calls $0,(r0) +- * calls $0,(r0) +- * +- * which is separated by only three bytes, thus HASHFRACTION is +- * calculated as: +- * +- * HASHFRACTION = 3 / (2 * 2 - 1) = 1 +- * +- * Note that the division above rounds down, thus if MIN_SUBR_FRACTION +- * is less than three, this algorithm will not work! +- * +- * In practice, however, call instructions are rarely at a minimal +- * distance. Hence, we will define HASHFRACTION to be 2 across all +- * architectures. This saves a reasonable amount of space for +- * profiling data structures without (in practice) sacrificing +- * any granularity. +- */ +-#define HASHFRACTION 2 +- +-/* +- * Percent of text space to allocate for tostructs. +- * This is a heuristic; we will fail with a warning when profiling programs +- * with a very large number of very small functions, but that's +- * normally OK. +- * 2 is probably still a good value for normal programs. +- * Profiling a test case with 64000 small functions will work if +- * you raise this value to 3 and link statically (which bloats the +- * text size, thus raising the number of arcs expected by the heuristic). +- */ +-#define ARCDENSITY 3 +- +-/* +- * Always allocate at least this many tostructs. This +- * hides the inadequacy of the ARCDENSITY heuristic, at least +- * for small programs. +- */ +-#define MINARCS 50 +- +-/* +- * The type used to represent indices into gmonparam.tos[]. +- */ +-#define ARCINDEX u_long +- +-/* +- * Maximum number of arcs we want to allow. +- * Used to be max representable value of ARCINDEX minus 2, but now +- * that ARCINDEX is a long, that's too large; we don't really want +- * to allow a 48 gigabyte table. +- * The old value of 1<<16 wasn't high enough in practice for large C++ +- * programs; will 1<<20 be adequate for long? FIXME +- */ +-#define MAXARCS (1 << 20) +- +-struct tostruct { +- u_long selfpc; +- long count; +- ARCINDEX link; +-}; +- +-/* +- * a raw arc, with pointers to the calling site and +- * the called site and a count. +- */ +-struct rawarc { +- u_long raw_frompc; +- u_long raw_selfpc; +- long raw_count; +-}; +- +-/* +- * general rounding functions. +- */ +-#define ROUNDDOWN(x,y) (((x)/(y))*(y)) +-#define ROUNDUP(x,y) ((((x)+(y)-1)/(y))*(y)) +- +-/* +- * The profiling data structures are housed in this structure. +- */ +-struct gmonparam { +- long int state; +- u_short *kcount; +- u_long kcountsize; +- ARCINDEX *froms; +- u_long fromssize; +- struct tostruct *tos; +- u_long tossize; +- long tolimit; +- u_long lowpc; +- u_long highpc; +- u_long textsize; +- u_long hashfraction; +- long log_hashfraction; +-}; +-extern struct gmonparam _gmonparam; +- +-/* +- * Possible states of profiling. +- */ +-#define GMON_PROF_ON 0 +-#define GMON_PROF_BUSY 1 +-#define GMON_PROF_ERROR 2 +-#define GMON_PROF_OFF 3 +- +-/* +- * Sysctl definitions for extracting profiling information from the kernel. +- */ +-#define GPROF_STATE 0 /* int: profiling enabling variable */ +-#define GPROF_COUNT 1 /* struct: profile tick count buffer */ +-#define GPROF_FROMS 2 /* struct: from location hash bucket */ +-#define GPROF_TOS 3 /* struct: destination/count structure */ +-#define GPROF_GMONPARAM 4 /* struct: profiling parameters (see above) */ +- +-__BEGIN_DECLS +- +-/* Set up data structures and start profiling. */ +-extern void __monstartup (u_long __lowpc, u_long __highpc) __THROW; +-extern void monstartup (u_long __lowpc, u_long __highpc) __THROW; +- +-/* Clean up profiling and write out gmon.out. */ +-extern void _mcleanup (void) __THROW; +- +-extern void __write_profiling (void); +-extern int attribute_hidden __profile_frequency (void); +- +-extern u_long __arc_profile_desc_secstart[], __arc_profile_desc_secend[]; +-extern u_long __arc_profile_forward_secstart[], __arc_profile_forward_secend[]; +-extern u_long __arc_profile_counters_secstart[]; +- +-__END_DECLS +- +-#endif /* sys/gmon.h */ +diff --git a/libgcc/config/arc/gmon/sys/gmon_out.h b/libgcc/config/arc/gmon/sys/gmon_out.h +deleted file mode 100644 +index d1f3b058a815..000000000000 +--- a/libgcc/config/arc/gmon/sys/gmon_out.h ++++ /dev/null +@@ -1,55 +0,0 @@ +-/* Copyright (C) 2007-2016 Free Software Foundation, Inc. +- Contributor: Joern Rennecke +- on behalf of Synopsys 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. +- +-Under Section 7 of GPL version 3, you are granted additional +-permissions described in the GCC Runtime Library Exception, version +-3.1, as published by the Free Software Foundation. +- +-You should have received a copy of the GNU General Public License and +-a copy of the GCC Runtime Library Exception along with this program; +-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +-. */ +- +-#define GMON_TAG_TIME_HIST 0 +-#define GMON_TAG_CG_ARC 1 +-#define GMON_TAG_BB_COUNT 2 +- +-#define GMON_MAGIC "gmon" +-#define GMON_VERSION 1 +- +-struct arc_gmon_hist_hdr +-{ +- char low_pc[4]; +- char high_pc[4]; +- char hist_size[4]; +- char prof_rate[4]; +- char dimen[15]; +- char dimen_abbrev; +-}; +- +-struct gmon_cg_arc_record +-{ +- char afrompc[4]; +- char selfpc[4]; +- char count[4]; +-}; +- +-struct gmon_hdr +-{ +- char cookie[4]; +- char version[4]; +- char c[12]; +-}; +diff --git a/libgcc/config/arc/t-arc b/libgcc/config/arc/t-arc +index 3523aedec13b..51a9273ec23b 100644 +--- a/libgcc/config/arc/t-arc ++++ b/libgcc/config/arc/t-arc +@@ -62,42 +62,5 @@ fp-bit.c: $(srcdir)/fp-bit.c + + # .init/.fini section routines + +-crtg.o: $(srcdir)/config/arc/crtg.S +- $(crt_compile) -c -x assembler-with-cpp $< +- +-crtgend.o: $(srcdir)/config/arc/crtgend.S +- $(crt_compile) -c -x assembler-with-cpp $< +- + crttls.o: $(srcdir)/config/arc/crttls.S + $(crt_compile) -c -x assembler-with-cpp $< +- +-mcount.o: $(srcdir)/config/arc/gmon/mcount.c +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< \ +- -fcall-saved-r0 -fcall-saved-r1 -fcall-saved-r2 -fcall-saved-r3 \ +- -fcall-saved-r4 -fcall-saved-r5 -fcall-saved-r6 -fcall-saved-r7 \ +- -fomit-frame-pointer +- +-gmon.o: $(srcdir)/config/arc/gmon/gmon.c +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -mno-sdata -c $< \ +- -fno-strict-aliasing \ +- -Wno-extra # suppress inane warning about missing initializer. +- # Adding initializers for the remaining elements of gmonparam would +- # make the code more brittle. +- +-prof-freq-stub.o: $(srcdir)/config/arc/gmon/prof-freq-stub.S +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< +- +-prof-freq.o: $(srcdir)/config/arc/gmon/prof-freq.c +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< +- +-dcache_linesz.o: $(srcdir)/config/arc/gmon/dcache_linesz.S +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< +- +-profil.o: $(srcdir)/config/arc/gmon/profil.S +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< +- +-profil-uclibc.o: $(srcdir)/config/arc/gmon/profil-uclibc.c +- $(gcc_compile) -isystem $(srcdir)/config/arc/gmon -c $< +- +-libgmon.a: mcount.o gmon.o dcache_linesz.o $(PROFILE_OSDEP) +- $(AR_CREATE_FOR_TARGET) $@ $^ +diff --git a/libgcc/config/arc/t-arc-newlib b/libgcc/config/arc/t-arc-newlib +deleted file mode 100644 +index f56b05259f03..000000000000 +--- a/libgcc/config/arc/t-arc-newlib ++++ /dev/null +@@ -1,22 +0,0 @@ +-# GCC Makefile fragment for the Synopsys DesignWare ARC CPU with newlib. +- +-# Copyright (C) 2007-2016 Free Software Foundation, Inc. +-# Contributor: Joern Rennecke +-# on behalf of Synopsys 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 +-# . +- +-PROFILE_OSDEP = prof-freq-stub.o profil.o +diff --git a/libgcc/config/arc/t-arc700-uClibc b/libgcc/config/arc/t-arc-uClibc +similarity index 98% +rename from libgcc/config/arc/t-arc700-uClibc +rename to libgcc/config/arc/t-arc-uClibc +index f5067cc01924..81156e8dc550 100644 +--- a/libgcc/config/arc/t-arc700-uClibc ++++ b/libgcc/config/arc/t-arc-uClibc +@@ -33,8 +33,6 @@ CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC + # Compile libgcc2.a with pic. + TARGET_LIBGCC2_CFLAGS = -fPIC + +-PROFILE_OSDEP = prof-freq.o +- + # Override t-slibgcc-elf-ver to hide some lib1func + # routines which should not be called via PLT. + SHLIB_MAPFILES = libgcc-std.ver $(srcdir)/config/arc/libgcc-excl.ver +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0040-ARC-Clean-up-arc-header-file.patch b/toolchain/gcc/patches/6.3.0/0040-ARC-Clean-up-arc-header-file.patch new file mode 100644 index 0000000..0457d6c --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0040-ARC-Clean-up-arc-header-file.patch @@ -0,0 +1,501 @@ +From cb3e1052fbbbde47c876fdb45e824879e080ba36 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 29 Jul 2016 15:30:00 +0200 +Subject: [PATCH 40/89] [ARC] Clean up arc header file. + +gcc/ +2016-07-29 Claudiu Zissulescu + + * config.gcc (arc*-): Clean up, use arc/big.h, arc/elf.h, and + arc/linux.h headers. + * config/arc/arc.h (TARGET_OS_CPP_BUILTINS): Remove. + (LINK_SPEC): Likewise. + (ARC_TLS_EXTRA_START_SPEC): Likewise. + (EXTRA_SPECS): Likewise. + (STARTFILE_SPEC): Likewise. + (ENDFILE_SPEC): Likewise. + (LIB_SPEC): Likewise. + (TARGET_SDATA_DEFAULT): Likewise. + (TARGET_MMEDIUM_CALLS_DEFAULT): Likewise. + (MULTILIB_DEFAULTS): Likewise. + (DWARF2_UNWIND_INFO): Likewise. + * config/arc/big.h: New file. + * config/arc/elf.h: Likewise. + * config/arc/linux.h: Likewise. + * config/arc/t-uClibc: Remove. +--- + gcc/config.gcc | 15 +++--- + gcc/config/arc/arc.h | 120 +++++------------------------------------------- + gcc/config/arc/big.h | 22 +++++++++ + gcc/config/arc/elf.h | 55 ++++++++++++++++++++++ + gcc/config/arc/linux.h | 76 ++++++++++++++++++++++++++++++ + gcc/config/arc/t-uClibc | 20 -------- + 6 files changed, 171 insertions(+), 137 deletions(-) + create mode 100644 gcc/config/arc/big.h + create mode 100644 gcc/config/arc/elf.h + create mode 100644 gcc/config/arc/linux.h + delete mode 100644 gcc/config/arc/t-uClibc + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 7b6138aec6bf..972f8f3ac130 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -326,6 +326,7 @@ arc*-*-*) + c_target_objs="arc-c.o" + cxx_target_objs="arc-c.o" + extra_options="${extra_options} arc/arc-tables.opt" ++ extra_headers="arc-simd.h" + ;; + arm*-*-*) + cpu_type=arm +@@ -1002,8 +1003,7 @@ alpha*-dec-*vms*) + tmake_file="${tmake_file} alpha/t-vms" + ;; + arc*-*-elf*) +- extra_headers="arc-simd.h" +- tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h ${tm_file}" ++ tm_file="arc/arc-arch.h dbxelf.h elfos.h newlib-stdint.h arc/elf.h ${tm_file}" + tmake_file="arc/t-multilib arc/t-arc" + extra_gcc_objs="driver-arc.o" + if test "x$with_cpu" != x; then +@@ -1020,15 +1020,12 @@ arc*-*-elf*) + *) echo "with_endian=${with_endian} not supported."; exit 1 ;; + esac + case ${with_endian} in +- big*) tm_defines="DRIVER_ENDIAN_SELF_SPECS=\\\"%{!EL:%{!mlittle-endian:-mbig-endian}}\\\" ${tm_defines}" ++ big*) tm_file="arc/big.h ${tm_file}" + esac + ;; + arc*-*-linux-uclibc*) +- extra_headers="arc-simd.h" +- tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h ${tm_file}" +- tmake_file="${tmake_file} arc/t-uClibc arc/t-arc" +- tm_defines="${tm_defines} TARGET_SDATA_DEFAULT=0" +- tm_defines="${tm_defines} TARGET_MMEDIUM_CALLS_DEFAULT=1" ++ tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arc/linux.h ${tm_file}" ++ tmake_file="${tmake_file} arc/t-arc" + extra_gcc_objs="driver-arc.o" + if test "x$with_cpu" != x; then + tm_defines="${tm_defines} TARGET_CPU_BUILD=PROCESSOR_$with_cpu" +@@ -1044,7 +1041,7 @@ arc*-*-linux-uclibc*) + *) echo "with_endian=${with_endian} not supported."; exit 1 ;; + esac + case ${with_endian} in +- big*) tm_defines="DRIVER_ENDIAN_SELF_SPECS=\\\"%{!EL:%{!mlittle-endian:-mbig-endian}}\\\" ${tm_defines}" ++ big*) tm_file="arc/big.h ${tm_file}" + esac + ;; + arm-wrs-vxworks) +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 3df21d416d97..5ca2bb5ffcd0 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1,14 +1,6 @@ + /* Definitions of target machine for GNU compiler, Synopsys DesignWare ARC cpu. + Copyright (C) 1994-2016 Free Software Foundation, Inc. + +- Sources derived from work done by Sankhya Technologies (www.sankhya.com) on +- behalf of Synopsys Inc. +- +- Position Independent Code support added,Code cleaned up, +- Comments and Support For ARC700 instructions added by +- Saurabh Verma (saurabh.verma@codito.com) +- Ramana Radhakrishnan(ramana.radhakrishnan@codito.com) +- + This file is part of GCC. + + GCC is free software; you can redistribute it and/or modify +@@ -57,32 +49,9 @@ along with GCC; see the file COPYING3. If not see + #define SYMBOL_REF_SHORT_CALL_P(X) \ + ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_SHORT_CALL) != 0) + +-#undef ASM_SPEC +-#undef LINK_SPEC +-#undef STARTFILE_SPEC +-#undef ENDFILE_SPEC +-#undef SIZE_TYPE +-#undef PTRDIFF_TYPE +-#undef WCHAR_TYPE +-#undef WCHAR_TYPE_SIZE +-#undef ASM_APP_ON +-#undef ASM_APP_OFF +-#undef CC1_SPEC +- + /* Names to predefine in the preprocessor for this target machine. */ + #define TARGET_CPU_CPP_BUILTINS() arc_cpu_cpp_builtins (pfile) + +-#if DEFAULT_LIBC == LIBC_UCLIBC +- +-#define TARGET_OS_CPP_BUILTINS() \ +- do \ +- { \ +- GNU_USER_TARGET_OS_CPP_BUILTINS (); \ +- } \ +- while (0) +- +-#endif /* DEFAULT_LIBC == LIBC_UCLIBC */ +- + /* Macros enabled by specific command line option. FIXME: to be + deprecatd. */ + #define CPP_SPEC "\ +@@ -95,6 +64,7 @@ along with GCC; see the file COPYING3. If not see + %{mlock:-D__Xlock} %{mswape:-D__Xswape} %{mrtsc:-D__Xrtsc} \ + %{mcpu=nps400:-D__NPS400__}" + ++#undef CC1_SPEC + #define CC1_SPEC "\ + %{EB:%{EL:%emay not use both -EB and -EL}} \ + %{EB:-mbig-endian} %{EL:-mlittle-endian} \ +@@ -104,71 +74,16 @@ extern const char *arc_cpu_to_as (int argc, const char **argv); + #define EXTRA_SPEC_FUNCTIONS \ + { "cpu_to_as", arc_cpu_to_as }, + ++#undef ASM_SPEC + #define ASM_SPEC "%{mbig-endian|EB:-EB} %{EL} " \ + "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}" + + #define OPTION_DEFAULT_SPECS \ + {"cpu", "%{!mcpu=*:%{!mARC*:%{!marc*:%{!mA7:%{!mA6:-mcpu=%(VALUE)}}}}}" } + +-#if DEFAULT_LIBC == LIBC_UCLIBC +-/* Note that the default is to link against dynamic libraries, if they are +- available. Override with -static. */ +-#define LINK_SPEC "%{h*} \ +- %{static:-Bstatic} \ +- %{symbolic:-Bsymbolic} \ +- %{rdynamic:-export-dynamic}\ +- -dynamic-linker /lib/ld-uClibc.so.0 \ +- -X %{mbig-endian:-EB} \ +- %{EB} %{EL} \ +- %{marclinux*} \ +- %{!marclinux*: -marclinux} \ +- %{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \ +- %{shared:-shared}" +-#else +-#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}" +-#endif +- +-#if DEFAULT_LIBC != LIBC_UCLIBC +-#define ARC_TLS_EXTRA_START_SPEC "crttls.o%s" +- +-#define EXTRA_SPECS \ +- { "arc_tls_extra_start_spec", ARC_TLS_EXTRA_START_SPEC }, \ +- +-#define STARTFILE_SPEC "%{pg|p:gcrt0.o%s}%{!pg:%{!p:crt0.o%s}} crti%O%s " \ +- "%(arc_tls_extra_start_spec) crtbegin.o%s" +-#else +-#define STARTFILE_SPEC \ +- LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, ANDROID_STARTFILE_SPEC) +-#endif +- +-#if DEFAULT_LIBC != LIBC_UCLIBC +-#define ENDFILE_SPEC "crtend.o%s crtn%O%s" +-#else +-#define ENDFILE_SPEC \ +- LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC) +-#endif +- +-#if DEFAULT_LIBC == LIBC_UCLIBC +-#undef LIB_SPEC +-#define LIB_SPEC \ +- "%{pthread:-lpthread} \ +- %{shared:-lc} \ +- %{!shared:%{profile:-lc_p}%{!profile:-lc}}" +-#define TARGET_ASM_FILE_END file_end_indicate_exec_stack +-#else +-#undef LIB_SPEC +-#define LIB_SPEC "%{!shared:%{g*:-lg} -lc}" +-#endif +- + #ifndef DRIVER_ENDIAN_SELF_SPECS + #define DRIVER_ENDIAN_SELF_SPECS "" + #endif +-#ifndef TARGET_SDATA_DEFAULT +-#define TARGET_SDATA_DEFAULT 1 +-#endif +-#ifndef TARGET_MMEDIUM_CALLS_DEFAULT +-#define TARGET_MMEDIUM_CALLS_DEFAULT 0 +-#endif + + #define DRIVER_SELF_SPECS DRIVER_ENDIAN_SELF_SPECS \ + "%{mARC600|mA6: -mcpu=arc600 %. */ ++ ++#undef DRIVER_ENDIAN_SELF_SPECS ++#define DRIVER_ENDIAN_SELF_SPECS "%{!EL:%{!mlittle-endian:-mbig-endian}}" +diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h +new file mode 100644 +index 000000000000..96565e53115e +--- /dev/null ++++ b/gcc/config/arc/elf.h +@@ -0,0 +1,55 @@ ++/* Target macros for arc*-elf targets. ++ ++ Copyright (C) 2016 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 ++. */ ++ ++#undef DWARF2_UNWIND_INFO ++#define DWARF2_UNWIND_INFO 0 ++ ++#undef LINK_SPEC ++#define LINK_SPEC "%{mbig-endian:-EB} %{EB} %{EL}" ++ ++#define ARC_TLS_EXTRA_START_SPEC "crttls.o%s" ++ ++#define EXTRA_SPECS \ ++ { "arc_tls_extra_start_spec", ARC_TLS_EXTRA_START_SPEC }, \ ++ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC "%{pg|p:gcrt0.o%s}%{!pg:%{!p:crt0.o%s}} crti%O%s " \ ++ "%(arc_tls_extra_start_spec) crtbegin.o%s" ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC "crtend.o%s crtn%O%s" ++ ++/* Leave the linker script to choose the appropriate libraries. */ ++#undef LIB_SPEC ++#define LIB_SPEC "" ++ ++/* SDATA default for elf. */ ++#undef TARGET_SDATA_DEFAULT ++#define TARGET_SDATA_DEFAULT 1 ++ ++/* We no medium calls. */ ++#undef TARGET_MMEDIUM_CALLS_DEFAULT ++#define TARGET_MMEDIUM_CALLS_DEFAULT 0 ++ ++#ifdef ARC_MULTILIB_CPU_DEFAULT ++# ifndef MULTILIB_DEFAULTS ++# define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT } ++# endif ++#endif +diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h +new file mode 100644 +index 000000000000..e4a881fa940d +--- /dev/null ++++ b/gcc/config/arc/linux.h +@@ -0,0 +1,76 @@ ++/* Target macros for arc*-*-linux targets. ++ ++ Copyright (C) 2016 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 ++. */ ++ ++/* Enable DWARF 2 exceptions. */ ++#undef DWARF2_UNWIND_INFO ++#define DWARF2_UNWIND_INFO 1 ++ ++#define TARGET_OS_CPP_BUILTINS() \ ++ do \ ++ { \ ++ GNU_USER_TARGET_OS_CPP_BUILTINS (); \ ++ } \ ++ while (0) ++ ++#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2" ++#define UCLIBC_DYNAMIC_LINKER "/lib/ld-uClibc.so.0" ++ ++/* Note that the default is to link against dynamic libraries, if they are ++ available. Override with -static. */ ++#undef LINK_SPEC ++#define LINK_SPEC "%{h*} \ ++ %{static:-Bstatic} \ ++ %{shared:-shared} \ ++ %{symbolic:-Bsymbolic} \ ++ %{!static: \ ++ %{rdynamic:-export-dynamic} \ ++ %{!shared:-dynamic-linker " GNU_USER_DYNAMIC_LINKER "}} \ ++ -X \ ++ %{mbig-endian:-EB} %{EB} %{EL} \ ++ %{!z:-z max-page-size=0x2000 -z common-page-size=0x2000} \ ++ -marclinux" ++ ++#undef STARTFILE_SPEC ++#define STARTFILE_SPEC \ ++ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_STARTFILE_SPEC, ANDROID_STARTFILE_SPEC) ++ ++#undef ENDFILE_SPEC ++#define ENDFILE_SPEC \ ++ LINUX_OR_ANDROID_LD (GNU_USER_TARGET_ENDFILE_SPEC, ANDROID_ENDFILE_SPEC) ++ ++#undef LIB_SPEC ++#define LIB_SPEC \ ++ "%{pthread:-lpthread} \ ++ %{shared:-lc} \ ++ %{!shared:%{profile:-lc_p}%{!profile:-lc}}" ++ ++#define TARGET_ASM_FILE_END file_end_indicate_exec_stack ++ ++/* No SDATA default for linux. */ ++#undef TARGET_SDATA_DEFAULT ++#define TARGET_SDATA_DEFAULT 0 ++ ++/* We have medium calls. */ ++#undef TARGET_MMEDIUM_CALLS_DEFAULT ++#define TARGET_MMEDIUM_CALLS_DEFAULT 1 ++ ++/* We do not have any MULTILIB_OPTIONS specified, so there are no ++ MULTILIB_DEFAULTS. */ ++#undef MULTILIB_DEFAULTS +diff --git a/gcc/config/arc/t-uClibc b/gcc/config/arc/t-uClibc +deleted file mode 100644 +index 11e81f1ee5ef..000000000000 +--- a/gcc/config/arc/t-uClibc ++++ /dev/null +@@ -1,20 +0,0 @@ +-# GCC Makefile fragment for Synopsys DesignWare ARC with uClibc +- +-# Copyright (C) 2007-2016 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 +-# . +- +-MULTILIB_EXTRA_OPTS = mno-sdata +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0041-ARC-Configure-script-to-allow-non-uclibc-based-tripl.patch b/toolchain/gcc/patches/6.3.0/0041-ARC-Configure-script-to-allow-non-uclibc-based-tripl.patch new file mode 100644 index 0000000..c03e541 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0041-ARC-Configure-script-to-allow-non-uclibc-based-tripl.patch @@ -0,0 +1,49 @@ +From 5a6e68beb138a8a30dfae633ceb6c24c4663d4e6 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 29 Jul 2016 16:04:33 +0200 +Subject: [PATCH 41/89] [ARC] Configure script to allow non uclibc based + triplets + +gcc/ +2016-07-28 Vineet Gupta + + * config.gcc (arc*-*-linux): Remove uclibc from arc target spec. + +libgcc/ +2016-07-28 Vineet Gupta + + * config.host (arc*-*-linux): Remove uclibc from arc target spec. +--- + gcc/config.gcc | 2 +- + libgcc/config.host | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/config.gcc b/gcc/config.gcc +index 972f8f3ac130..a3cfcc2aa2fa 100644 +--- a/gcc/config.gcc ++++ b/gcc/config.gcc +@@ -1023,7 +1023,7 @@ arc*-*-elf*) + big*) tm_file="arc/big.h ${tm_file}" + esac + ;; +-arc*-*-linux-uclibc*) ++arc*-*-linux*) + tm_file="arc/arc-arch.h dbxelf.h elfos.h gnu-user.h linux.h linux-android.h glibc-stdint.h arc/linux.h ${tm_file}" + tmake_file="${tmake_file} arc/t-arc" + extra_gcc_objs="driver-arc.o" +diff --git a/libgcc/config.host b/libgcc/config.host +index 035d38d03713..092b00268cc7 100644 +--- a/libgcc/config.host ++++ b/libgcc/config.host +@@ -369,7 +369,7 @@ arc*-*-elf*) + extra_parts="crti.o crtn.o crtend.o crtbegin.o crtendS.o crtbeginS.o" + extra_parts="$extra_parts crttls.o" + ;; +-arc*-*-linux-uclibc*) ++arc*-*-linux*) + tmake_file="${tmake_file} t-slibgcc-libgcc t-slibgcc-nolc-override arc/t-arc-uClibc arc/t-arc" + extra_parts="$extra_parts crti.o crtn.o" + extra_parts="$extra_parts crttls.o" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0042-ARC-Fix-conditional-move-contstraint.patch b/toolchain/gcc/patches/6.3.0/0042-ARC-Fix-conditional-move-contstraint.patch new file mode 100644 index 0000000..6589664 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0042-ARC-Fix-conditional-move-contstraint.patch @@ -0,0 +1,32 @@ +From 7cf41ca830af0de2cc7c0222d96b40921c02ffb1 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 22 Aug 2016 19:58:25 +0200 +Subject: [PATCH 42/89] [ARC] Fix conditional move contstraint + +Move pattern (movsi_insn) allows predicated instructions to be +instructions which can hold all registers. However, the conditional +variant doesn't. This patch fixes this problem. + +2016-08-22 Claudiu Zissulescu + + * config/arc/arc.md (movsi_cond_exec): Update constraint. +--- + gcc/config/arc/arc.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index d87174a7f321..607c6e6614e6 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -3603,7 +3603,7 @@ + (match_operator 3 "proper_comparison_operator" + [(match_operand 2 "cc_register" "Rcc,Rcc") (const_int 0)]) + (set (match_operand:SI 0 "dest_reg_operand" "=w,w") +- (match_operand:SI 1 "nonmemory_operand" "Lc,?Cal")))] ++ (match_operand:SI 1 "nonmemory_operand" "LRac,?Cal")))] + "" + "mov.%d3 %0,%S1" + [(set_attr "type" "cmove") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0043-Fix-tst_bitfield_tst-pattern.patch b/toolchain/gcc/patches/6.3.0/0043-Fix-tst_bitfield_tst-pattern.patch new file mode 100644 index 0000000..f8730d9 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0043-Fix-tst_bitfield_tst-pattern.patch @@ -0,0 +1,66 @@ +From a4c30f398ad4feb3ec5133397a2e93b886a263ae Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 7 Sep 2016 13:04:32 +0200 +Subject: [PATCH 43/89] Fix tst_bitfield_tst pattern. + +gcc/ +2016-09-07 Claudiu Zissulescu + + * config/arc/arc.md (*tst_bitfield_tst): Fix pattern. + * testsuite/gcc.target/arc/bitfield.c: New file. +--- + gcc/config/arc/arc.md | 2 +- + gcc/testsuite/gcc.target/arc/bitfield.c | 28 ++++++++++++++++++++++++++++ + 2 files changed, 29 insertions(+), 1 deletion(-) + create mode 100755 gcc/testsuite/gcc.target/arc/bitfield.c + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 607c6e6614e6..a7ffed3f0c52 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -888,7 +888,7 @@ + && (INTVAL (operands[3]) + INTVAL (operands[2]) <= 11 + || (INTVAL (operands[3]) <= 11 + && INTVAL (operands[3]) + INTVAL (operands[2]) == 32))" +- "tst %1,(1<<%2)-1<<%3" ++ "tst %1,((1<<%2)-1)<<%3" + [(set_attr "type" "compare") + (set_attr "cond" "set_zn") + (set_attr "length" "4")]) +diff --git a/gcc/testsuite/gcc.target/arc/bitfield.c b/gcc/testsuite/gcc.target/arc/bitfield.c +new file mode 100755 +index 000000000000..187cd1ddb5fe +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/bitfield.c +@@ -0,0 +1,28 @@ ++/* { dg-do run } */ ++/* { dg-options "-O2" } */ ++ ++#include ++ ++struct ubifs_budget_req { ++ unsigned int fast:7; ++ unsigned int new_ino_d:13; ++}; ++ ++int printf(const char *format, ...); ++ ++void __attribute__ ((noinline)) ++fff(struct ubifs_budget_req *req) ++{ ++ if (req->new_ino_d & 7) ++ abort (); ++} ++ ++int main (void) ++{ ++ struct ubifs_budget_req req = { ++ .fast = 8, ++ .new_ino_d = 0, ++ }; ++ fff(&req); ++ return 0; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0044-ARC-Prohibit-negative-PIC-constants.patch b/toolchain/gcc/patches/6.3.0/0044-ARC-Prohibit-negative-PIC-constants.patch new file mode 100644 index 0000000..e952b16 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0044-ARC-Prohibit-negative-PIC-constants.patch @@ -0,0 +1,105 @@ +From b0d9ad169e43483872e95a3a6901407b565bbc74 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 15 Sep 2016 15:06:24 +0200 +Subject: [PATCH 44/89] [ARC] Prohibit negative PIC constants. + +Avoid to generate a PIC constant which uses neg code. + +gcc/ +2016-09-15 Claudiu Zissulescu + + * testsuite/gcc.target/arc/pr9000674901.c: New file. + * config/arc/arc.c (arc_legitimate_constant_p): Avoid negative PIC + constants. +--- + gcc/config/arc/arc.c | 8 ++++ + gcc/testsuite/gcc.target/arc/pr9000674901.c | 58 +++++++++++++++++++++++++++++ + 2 files changed, 66 insertions(+) + create mode 100644 gcc/testsuite/gcc.target/arc/pr9000674901.c + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 4e478131da35..2135bf0f8cd2 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -5461,6 +5461,14 @@ arc_legitimate_constant_p (machine_mode mode, rtx x) + x = XEXP (x, 0); + } + ++ if (GET_CODE (x) == NEG) ++ { ++ /* Assembler does not understand -(@label@gotoff). Also, we ++ do not print such pic address constant. */ ++ if (GET_CODE (XEXP (x, 0)) == UNSPEC) ++ return false; ++ } ++ + /* Only some unspecs are valid as "constants". */ + if (GET_CODE (x) == UNSPEC) + switch (XINT (x, 1)) +diff --git a/gcc/testsuite/gcc.target/arc/pr9000674901.c b/gcc/testsuite/gcc.target/arc/pr9000674901.c +new file mode 100644 +index 000000000000..2a15c1c1478e +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/pr9000674901.c +@@ -0,0 +1,58 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "" { ! { clmcpu } } } */ ++/* { dg-options "-mcpu=arc700 -O2 -fpic" } */ ++ ++/* Test if the compiler generates a constant address having that uses ++ a neg keyword on the pic unspec. */ ++ ++typedef unsigned int uint32_t; ++typedef unsigned char uint8_t; ++typedef unsigned short int uint16_t; ++typedef unsigned long long int uint64_t; ++ ++enum type { ++ t_undef = 0x01, ++ t_group = 0x02, ++ t_partition = 0x04, ++ t_spare = 0x08, ++ t_linear = 0x10, ++ t_raid0 = 0x20, ++ t_raid1 = 0x40, ++ t_raid4 = 0x80, ++ t_raid5_ls = 0x100, ++ t_raid5_rs = 0x200, ++ t_raid5_la = 0x400, ++ t_raid5_ra = 0x800, ++ t_raid6 = 0x1000, ++}; ++ ++struct raid_set { ++ enum type type; ++}; ++ ++void ++_find_factors (struct raid_set *rs, uint8_t * div, uint8_t * sub) ++{ ++ struct factors { ++ const uint8_t level; ++ const uint8_t div, sub; ++ }; ++ static struct factors factors[] = { ++ {0, 1, 0}, ++ {1, 2, 0}, ++ {2, 2, 0}, ++ {5, 1, 1}, ++ }; ++ struct factors *f = (factors + (sizeof (factors) / sizeof (*factors))); ++ ++ while (f-- > factors) { ++ if (rs->type == f->level) { ++ *div = f->div; ++ *sub = f->sub; ++ return; ++ } ++ } ++ ++ *div = 1; ++ *sub = 0; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0045-ARC-Handle-complex-PIC-move-patterns.patch b/toolchain/gcc/patches/6.3.0/0045-ARC-Handle-complex-PIC-move-patterns.patch new file mode 100644 index 0000000..9aa1f07 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0045-ARC-Handle-complex-PIC-move-patterns.patch @@ -0,0 +1,120 @@ +From 17cba35c2d8f0a42b732e6d3b33d5ce608f2a3f3 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 16 Sep 2016 14:13:59 +0200 +Subject: [PATCH 45/89] [ARC] Handle complex PIC move patterns. + +fwprop step is placing in the REG_EQUIV notes constant pic unspecs +expressions. Then, loop may use these notes for optimizations +rezulting in complex patterns that are not supported by the current +implementation. + +The patch adds handling of complex PIC addresses having MINUS or UNARY +operations. + +gcc/ +2016-09-16 Claudiu Zissulescu + + * config/arc/arc.c (arc_legitimize_pic_address): Handle PIC + expressions with MINUS and UNARY ops. + * testsuite/gcc.target/arc/pr9001090948.c: New file. +--- + gcc/config/arc/arc.c | 49 ++++++++++++++++++++++++++++- + gcc/testsuite/gcc.target/arc/pr9001090948.c | 25 +++++++++++++++ + 2 files changed, 73 insertions(+), 1 deletion(-) + create mode 100644 gcc/testsuite/gcc.target/arc/pr9001090948.c + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 2135bf0f8cd2..e8a157aab33d 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -5028,8 +5028,55 @@ arc_legitimize_pic_address (rtx orig, rtx oldx) + /* Check that the unspec is one of the ones we generate? */ + return orig; + } ++ /* fwprop is placing in the REG_EQUIV notes constant pic ++ unspecs expressions. Then, loop may use these notes for ++ optimizations rezulting in complex patterns that are not ++ supported by the current implementation. The following ++ two if-cases are simplifying the complex patters in ++ simpler ones. */ ++ else if (GET_CODE (addr) == MINUS) ++ { ++ rtx op0 = XEXP (addr, 0); ++ rtx op1 = XEXP (addr, 1); ++ gcc_assert (oldx); ++ gcc_assert (GET_CODE (op1) == UNSPEC); ++ ++ emit_move_insn (oldx, ++ gen_rtx_CONST (SImode, ++ arc_legitimize_pic_address (op1, ++ NULL_RTX))); ++ emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx))); ++ return oldx; ++ ++ } ++ else if (GET_CODE (addr) != PLUS) ++ { ++ rtx tmp = XEXP (addr, 0); ++ enum rtx_code code = GET_CODE (addr); ++ ++ /* It only works for UNARY operations. */ ++ gcc_assert (UNARY_P (addr)); ++ gcc_assert (GET_CODE (tmp) == UNSPEC); ++ gcc_assert (oldx); ++ ++ emit_move_insn ++ (oldx, ++ gen_rtx_CONST (SImode, ++ arc_legitimize_pic_address (tmp, ++ NULL_RTX))); ++ ++ emit_insn (gen_rtx_SET (oldx, ++ gen_rtx_fmt_ee (code, SImode, ++ oldx, const0_rtx))); ++ ++ return oldx; ++ } + else +- gcc_assert (GET_CODE (addr) == PLUS); ++ { ++ gcc_assert (GET_CODE (addr) == PLUS); ++ if (GET_CODE (XEXP (addr, 0)) == UNSPEC) ++ return orig; ++ } + } + + if (GET_CODE (addr) == PLUS) +diff --git a/gcc/testsuite/gcc.target/arc/pr9001090948.c b/gcc/testsuite/gcc.target/arc/pr9001090948.c +new file mode 100644 +index 000000000000..103f4aee7ec5 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/pr9001090948.c +@@ -0,0 +1,25 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "ARC600 doesn't support pic" { arc6xx } } */ ++/* { dg-options "-Os -fPIC" } */ ++#include ++#include ++ ++char * ++strip_trail (const char str[], size_t n) ++{ ++ static char buf[1025]; ++ int j; ++ ++ strncpy (buf, str, n); ++ buf[n] = '\0'; ++ ++ for (j = strlen (buf) - 1; j >= 0; j--) ++ { ++ if (buf[j] != ' ') ++ break; ++ ++ buf[j] = '\0'; ++ } ++ ++ return buf; ++} +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0046-ARC-Add-code-density-instructions.patch b/toolchain/gcc/patches/6.3.0/0046-ARC-Add-code-density-instructions.patch new file mode 100644 index 0000000..9f6d36f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0046-ARC-Add-code-density-instructions.patch @@ -0,0 +1,300 @@ +From 10a2b73d90a8a365037431ce8e5edb86b7d86d0b Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 16 Sep 2016 17:46:56 +0200 +Subject: [PATCH 46/89] [ARC] Add code density instructions. + +gcc/ +2016-09-16 Claudiu Zissulescu + + * config/arc/arc.c (arc_output_addsi): Emit code density adds. + * config/arc/arc.md (cpu_facility): Add cd variant. + (*movqi_insn): Add code density variant. + (*movhi_insn): Likewise. + (*movqi_insn): Likewise. + (*addsi3_mixed): Likewise. + (subsi3_insn): Likewise. +--- + gcc/config/arc/arc.c | 11 +++++ + gcc/config/arc/arc.md | 130 ++++++++++++++++++++++++++++---------------------- + 2 files changed, 84 insertions(+), 57 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index e8a157aab33d..498bdfd422dd 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -7396,6 +7396,17 @@ arc_output_addsi (rtx *operands, bool cond_p, bool output_p) + || (REGNO (operands[0]) == STACK_POINTER_REGNUM + && match && !(neg_intval & ~124))) + ADDSI_OUTPUT1 ("sub%? %0,%1,%n2"); ++ ++ if (REG_P(operands[0]) && REG_P(operands[1]) ++ && (REGNO(operands[0]) <= 31) && (REGNO(operands[0]) == REGNO(operands[1])) ++ && CONST_INT_P (operands[2]) && ( (intval>= -1) && (intval <= 6))) ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2"); ++ ++ if (TARGET_CODE_DENSITY && REG_P(operands[0]) && REG_P(operands[1]) ++ && ((REGNO(operands[0]) == 0) || (REGNO(operands[0]) == 1)) ++ && satisfies_constraint_Rcq (operands[1]) ++ && satisfies_constraint_L (operands[2])) ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3"); + } + + /* Now try to emit a 32 bit insn without long immediate. */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index a7ffed3f0c52..2b239d7268f5 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -261,7 +261,7 @@ + - get_attr_length (insn)"))) + + ; for ARCv2 we need to disable/enable different instruction alternatives +-(define_attr "cpu_facility" "std,av1,av2,fpx" ++(define_attr "cpu_facility" "std,av1,av2,fpx,cd" + (const_string "std")) + + ; We should consider all the instructions enabled until otherwise +@@ -277,6 +277,11 @@ + (and (eq_attr "cpu_facility" "fpx") + (match_test "TARGET_FP_DP_AX")) + (const_string "no") ++ ++ (and (eq_attr "cpu_facility" "cd") ++ (not (and (match_test "TARGET_V2") ++ (match_test "TARGET_CODE_DENSITY")))) ++ (const_string "no") + ] + (const_string "yes"))) + +@@ -611,8 +616,8 @@ + ; The iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + (define_insn "*movqi_insn" +- [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w, w,Rcq, S,!*x, r,r, Ucm,m,???m") +- (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac"))] ++ [(set (match_operand:QI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w,???w,h, w,Rcq, S,!*x, r,r, Ucm,m,???m,Usc") ++ (match_operand:QI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL,I,?Rac,i,?i, T,Rcq,Usd,Ucm,m,?Rac,c,?Rac,Cm3"))] + "register_operand (operands[0], QImode) + || register_operand (operands[1], QImode)" + "@ +@@ -620,6 +625,8 @@ + mov%? %0,%1%& + mov%? %0,%1%& + mov%? %0,%1%& ++ mov%? %0,%1%& ++ mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%1 +@@ -631,11 +638,12 @@ + ldb%U1%V1 %0,%1 + xstb%U0 %1,%0 + stb%U0%V0 %1,%0 ++ stb%U0%V0 %1,%0 + stb%U0%V0 %1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,false,true,true,true,false,false,false,false,false") +- (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,load,store,load,load,load,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,false,true,true,true,false,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) + + (define_expand "movhi" + [(set (match_operand:HI 0 "move_dest_operand" "") +@@ -644,8 +652,8 @@ + "if (prepare_move_operands (operands, HImode)) DONE;") + + (define_insn "*movhi_insn" +- [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w,???w,Rcq#q, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc") +- (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q,hCm1,cL,I,?Rac, ?i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))] ++ [(set (match_operand:HI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w,???w,Rcq#q,h, w,Rcq, S, r,r, Ucm,m,???m,VUsc,VUsc") ++ (match_operand:HI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL,I,?Rac, i,i,?i, T,Rcq,Ucm,m,?Rac,c,?Rac, Cm3,i"))] + "register_operand (operands[0], HImode) + || register_operand (operands[1], HImode) + || (CONSTANT_P (operands[1]) +@@ -658,11 +666,13 @@ + mov%? %0,%1%& + mov%? %0,%1%& + mov%? %0,%1%& ++ mov%? %0,%1%& + mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%1 + mov%? %0,%S1%& + mov%? %0,%S1 ++ mov%? %0,%S1 + ld%_%? %0,%1%& + st%_%? %1,%0%& + xld%_%U1 %0,%1 +@@ -672,10 +682,10 @@ + st%_%U0%V0 %1,%0 + st%_%U0%V0 %S1,%0 + st%_%U0%V0 %S1,%0" +- [(set_attr "type" "move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,true,false,false,false,maybe_limm,false,true,true,false,false,false,false,false,false,false") +- (set_attr "predicable" "yes,no,yes,no,yes,no,yes,yes,yes,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "*,*,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")]) ++ [(set_attr "type" "move,move,move,move,move,move,move,move,move,move,move,load,store,load,load,store,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false,false,maybe_limm,maybe_limm,false,true,true,false,false,false,false,false,false,false") ++ (set_attr "predicable" "yes,no,yes,no,no,yes,no,yes,yes,yes,yes,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,*")]) + + (define_expand "movsi" + [(set (match_operand:SI 0 "move_dest_operand" "") +@@ -693,9 +703,9 @@ + ; the iscompact attribute allows the epilogue expander to know for which + ; insns it should lengthen the return insn. + ; N.B. operand 1 of alternative 7 expands into pcl,symbol@gotpc . +-(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 +- [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") +- (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q,hPCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] ++(define_insn "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ++ [(set (match_operand:SI 0 "move_dest_operand" "=Rcq,Rcq#q, w,Rcq#q, h, w,w, w, w, w, w,???w, ?w, w,Rcq#q, h, w,Rcq, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m,???m,VUsc,VUsc") ++ (match_operand:SI 1 "move_src_operand" " cL, cP,Rcq#q, P,hCm1,cL,I,Crr,Clo,Chi,Cbi,?Rac,Cpc,Clb, ?Cal,Cal,?Cal, T,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, w,!*Rzd,c,?Rac, Cm3, C32"))] + "register_operand (operands[0], SImode) + || register_operand (operands[1], SImode) + || (CONSTANT_P (operands[1]) +@@ -708,39 +718,42 @@ + mov%? %0,%1%& ;1 + mov%? %0,%1%& ;2 + mov%? %0,%1%& ;3 +- mov%? %0,%1 ;4 ++ mov%? %0,%1%& ;4 + mov%? %0,%1 ;5 +- ror %0,((%1*2+1) & 0x3f) ;6 +- movl.cl %0,%1 ;7 +- movh.cl %0,%L1>>16 ;8 +- * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;8\" : \"movbi.cl %0,%L1 >> 24,24,8;9\"; +- mov%? %0,%1 ;10 +- add %0,%S1 ;11 +- add %0,pcl,%1@pcl ;12 +- mov%? %0,%S1%& ;13 +- mov%? %0,%S1 ;14 +- ld%? %0,%1%& ;15 +- st%? %1,%0%& ;16 ++ mov%? %0,%1 ;6 ++ ror %0,((%1*2+1) & 0x3f) ;7 ++ movl.cl %0,%1 ;8 ++ movh.cl %0,%L1>>16 ;9 ++ * return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl %0,%1 >> %p1,%p1,8;10\" : \"movbi.cl %0,%L1 >> 24,24,8;10\"; ++ mov%? %0,%1 ;11 ++ add %0,%S1 ;12 ++ add %0,pcl,%1@pcl ;13 ++ mov%? %0,%S1%& ;14 ++ mov%? %0,%S1 ;15 ++ mov%? %0,%S1 ;16 ++ ld%? %0,%1%& ;17 ++ st%? %1,%0%& ;18 + * return arc_short_long (insn, \"push%? %1%&\", \"st%U0 %1,%0%&\"); + * return arc_short_long (insn, \"pop%? %0%&\", \"ld%U1 %0,%1%&\"); +- ld%? %0,%1%& ;19 +- xld%U1 %0,%1 ;20 + ld%? %0,%1%& ;21 +- ld%? %0,%1%& ;22 +- ld%U1%V1 %0,%1 ;23 +- xst%U0 %1,%0 ;24 +- st%? %1,%0%& ;25 +- st%U0%V0 %1,%0 ;26 +- st%U0%V0 %1,%0 ;27 ++ xld%U1 %0,%1 ;22 ++ ld%? %0,%1%& ;23 ++ ld%? %0,%1%& ;24 ++ ld%U1%V1 %0,%1 ;25 ++ xst%U0 %1,%0 ;26 ++ st%? %1,%0%& ;27 + st%U0%V0 %1,%0 ;28 +- st%U0%V0 %S1,%0 ;29" +- [(set_attr "type" "move,move,move,move,move,move,two_cycle_core,shift,shift,shift,move,binary,binary,move,move,load,store,store,load,load,load,load,load,load,store,store,store,store,store,store") +- (set_attr "iscompact" "maybe,maybe,maybe,false,false,false,false,false,false,false,false,false,maybe_limm,false,true,true,true,true,true,false,false,false,false,false,false,false,false,false,false,false") ++ st%U0%V0 %1,%0 ;29 ++ st%U0%V0 %1,%0 ;30 ++ st%U0%V0 %S1,%0 ;31" ++ ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ++ [(set_attr "type" "move, move, move,move,move, move, move,two_cycle_core,shift,shift,shift, move,binary,binary, move, move, move,load,store,store,load,load, load,load,load, load,store,store,store,store,store,store") ++ (set_attr "iscompact" "maybe,maybe,maybe,true,true,false,false, false,false,false,false,false, false, false,maybe_limm,maybe_limm,false,true, true, true,true,true,false,true,true,false,false, true,false,false,false,false") + ; Use default length for iscompact to allow for COND_EXEC. But set length + ; of Crr to 4. +- (set_attr "length" "*,*,*,*,4,4,4,4,4,4,4,8,8,*,8,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8") +- (set_attr "predicable" "yes,no,yes,no,yes,no,no,no,no,no,yes,no,no,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") +- (set_attr "cpu_facility" "av1,av1,av1,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) ++ (set_attr "length" "*,*,*,*,*,4,4,4,4,4,4,4,8,8,*,*,*,*,*,*,*,*,4,*,4,*,*,*,*,*,4,8") ++ (set_attr "predicable" "yes,no,yes,no,no,yes,no,no,no,no,no,yes,no,no,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no,no,no,no") ++ (set_attr "cpu_facility" "av1,av1,av1,av2,av2,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,av2,av2,*,*,av2,*,*,av2,*")]) + + ;; Sometimes generated by the epilogue code. We don't want to + ;; recognize these addresses in general, because the limm is costly, +@@ -1755,10 +1768,10 @@ + ; We avoid letting this pattern use LP_COUNT as a register by specifying + ; register class 'W' instead of 'w'. + (define_insn_and_split "*addsi3_mixed" +- ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq,Rcw,Rcw,Rcq,Rcb,Rcq, Rcw, Rcqq,Rcqq, W, W,W, W,Rcqq,Rcw, W") +- (plus:SI (match_operand:SI 1 "register_operand" "%0, c, 0, c, 0, 0,Rcb, 0, Rcqq, 0, c, c,0, 0, 0, 0, c") +- (match_operand:SI 2 "nonmemory_operand" "cL, 0, cL, 0,CL2,Csp,CM4,cCca,RcqqK, cO,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))] ++ ;; 0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcq#q,Rcq, h,!*Rsd,Rcq,Rcb,Rcq, Rcqq,Rcqq,Rcw,Rcw, Rcw, W, W,W, W,Rcqq,Rcw, W") ++ (plus:SI (match_operand:SI 1 "register_operand" "%0, c, 0, Rcqq, 0, 0,Rcb, Rcqq, 0, 0, c, 0, c, c,0, 0, 0, 0, c") ++ (match_operand:SI 2 "nonmemory_operand" "cL, 0, Cm1, L,CL2,Csp,CM4,RcqqK, cO, cL, 0,cCca,cLCmL,Cca,I,C2a, Cal,Cal,Cal")))] + "" + { + arc_output_addsi (operands, arc_ccfsm_cond_exec_p (), true); +@@ -1769,16 +1782,16 @@ + && GET_CODE (PATTERN (insn)) != COND_EXEC" + [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))] + "split_addsi (operands);" +- [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,two_cycle_core,*,*,*,two_cycle_core,*,two_cycle_core,*,*,*") ++ [(set_attr "type" "*,*,*,*,two_cycle_core,two_cycle_core,*,*,*,*,*,two_cycle_core,*,two_cycle_core,*,two_cycle_core,*,*,*") + (set (attr "iscompact") + (cond [(match_test "~arc_output_addsi (operands, false, false) & 2") + (const_string "false") + (match_operand 2 "long_immediate_operand" "") + (const_string "maybe_limm")] + (const_string "maybe"))) +- (set_attr "length" "*,*,4,4,*,*,*,4,*,*,4,4,4,4,*,8,8") +- (set_attr "predicable" "no,no,yes,yes,no,no,no,yes,no,no,no,no,no,no,no,yes,no") +- (set_attr "cond" "canuse,canuse,canuse,canuse,canuse,canuse,nocond,canuse,nocond,nocond,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond") ++ (set_attr "length" "*,*,*,*,*,*,*,*,*,4,4,4,4,4,4,4,*,8,8") ++ (set_attr "predicable" "no,no,no,no,no,no,no,no,no,yes,yes,yes,no,no,no,no,no,yes,no") ++ (set_attr "cond" "canuse,nocond,nocond,nocond,canuse,canuse,nocond,nocond,nocond,canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse_limm,canuse,canuse,nocond") + ]) + + ;; ARCv2 MPYW and MPYUW +@@ -2723,13 +2736,14 @@ + ; the casesi expander might generate a sub of zero, so we have to recognize it. + ; combine should make such an insn go away. + (define_insn_and_split "subsi3_insn" +- [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcw,Rcw,w,w,w, w, w, w") +- (minus:SI (match_operand:SI 1 "nonmemory_operand" "0, 0, cL,c,L,I,Cal,Cal, c") +- (match_operand:SI 2 "nonmemory_operand" "Rcqq, c, 0,c,c,0, 0, c,Cal")))] ++ [(set (match_operand:SI 0 "dest_reg_operand" "=Rcqq,Rcqq,Rcw,Rcw,w,w,w, w, w, w") ++ (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,Rcqq, 0, cL,c,L,I,Cal,Cal, c") ++ (match_operand:SI 2 "nonmemory_operand" "Rcqq,Rcqq, c, 0,c,c,0, 0, c,Cal")))] + "register_operand (operands[1], SImode) + || register_operand (operands[2], SImode)" + "@ + sub%? %0,%1,%2%& ++ sub%? %0,%1,%2%& + sub%? %0,%1,%2 + rsub%? %0,%2,%1 + sub %0,%1,%2 +@@ -2743,10 +2757,12 @@ + && GET_CODE (PATTERN (insn)) != COND_EXEC" + [(set (match_dup 0) (match_dup 3)) (set (match_dup 0) (match_dup 4))] + "split_subsi (operands);" +- [(set_attr "iscompact" "maybe,false,false,false,false,false,false,false, false") +- (set_attr "length" "*,4,4,4,4,4,8,8,8") +- (set_attr "predicable" "yes,yes,yes,no,no,no,yes,no,no") +- (set_attr "cond" "canuse,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond")]) ++ [(set_attr "iscompact" "maybe,maybe,false,false,false,false,false,false,false, false") ++ (set_attr "length" "*,*,4,4,4,4,4,8,8,8") ++ (set_attr "predicable" "yes,no,yes,yes,no,no,no,yes,no,no") ++ (set_attr "cond" "canuse,nocond,canuse,canuse,nocond,nocond,canuse_limm,canuse,nocond,nocond") ++ (set_attr "cpu_facility" "*,cd,*,*,*,*,*,*,*,*") ++ ]) + + (define_expand "subdi3" + [(parallel [(set (match_operand:DI 0 "dest_reg_operand" "") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0047-ARC-Code-size-modifications.patch b/toolchain/gcc/patches/6.3.0/0047-ARC-Code-size-modifications.patch new file mode 100644 index 0000000..2cbdad0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0047-ARC-Code-size-modifications.patch @@ -0,0 +1,107 @@ +From 3a58d7260e0f74fa16afbca0fd18c7d57748d3de Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 20 Sep 2016 13:27:56 +0200 +Subject: [PATCH 47/89] [ARC] Code size modifications. + +gcc/ +2016-09-20 Claudiu Zissulescu + + * config/arc/arc.c (arc_init): Use multiplier whenever we have it. + (arc_conditional_register_usage): Use a different allocation order + when optimizing for size. + * common/config/arc/arc-common.c (arc_option_optimization_table): + Section anchors default on when optimizing for size. +--- + gcc/common/config/arc/arc-common.c | 1 + + gcc/config/arc/arc.c | 56 ++++++++++++++++++++++++++++---------- + 2 files changed, 43 insertions(+), 14 deletions(-) + +diff --git a/gcc/common/config/arc/arc-common.c b/gcc/common/config/arc/arc-common.c +index 289886006380..8a9acb6239e3 100644 +--- a/gcc/common/config/arc/arc-common.c ++++ b/gcc/common/config/arc/arc-common.c +@@ -46,6 +46,7 @@ arc_option_init_struct (struct gcc_options *opts) + #define OPT_LEVELS_3_PLUS_SPEED_ONLY OPT_LEVELS_3_PLUS + static const struct default_options arc_option_optimization_table[] = + { ++ { OPT_LEVELS_SIZE, OPT_fsection_anchors, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 }, + { OPT_LEVELS_ALL, OPT_mRcq, NULL, 1 }, + { OPT_LEVELS_ALL, OPT_mRcw, NULL, 1 }, +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 498bdfd422dd..379b70011f2b 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -685,6 +685,12 @@ make_pass_arc_predicate_delay_insns (gcc::context *ctxt) + static void + arc_init (void) + { ++ if (TARGET_V2) ++ { ++ /* I have the multiplier, then use it*/ ++ if (TARGET_MPYW || TARGET_MULTI) ++ arc_multcost = COSTS_N_INSNS (1); ++ } + /* Note: arc_multcost is only used in rtx_cost if speed is true. */ + if (arc_multcost < 0) + switch (arc_tune) +@@ -1382,20 +1388,42 @@ arc_conditional_register_usage (void) + } + if (TARGET_Q_CLASS) + { +- reg_alloc_order[2] = 12; +- reg_alloc_order[3] = 13; +- reg_alloc_order[4] = 14; +- reg_alloc_order[5] = 15; +- reg_alloc_order[6] = 1; +- reg_alloc_order[7] = 0; +- reg_alloc_order[8] = 4; +- reg_alloc_order[9] = 5; +- reg_alloc_order[10] = 6; +- reg_alloc_order[11] = 7; +- reg_alloc_order[12] = 8; +- reg_alloc_order[13] = 9; +- reg_alloc_order[14] = 10; +- reg_alloc_order[15] = 11; ++ if (optimize_size) ++ { ++ reg_alloc_order[0] = 0; ++ reg_alloc_order[1] = 1; ++ reg_alloc_order[2] = 2; ++ reg_alloc_order[3] = 3; ++ reg_alloc_order[4] = 12; ++ reg_alloc_order[5] = 13; ++ reg_alloc_order[6] = 14; ++ reg_alloc_order[7] = 15; ++ reg_alloc_order[8] = 4; ++ reg_alloc_order[9] = 5; ++ reg_alloc_order[10] = 6; ++ reg_alloc_order[11] = 7; ++ reg_alloc_order[12] = 8; ++ reg_alloc_order[13] = 9; ++ reg_alloc_order[14] = 10; ++ reg_alloc_order[15] = 11; ++ } ++ else ++ { ++ reg_alloc_order[2] = 12; ++ reg_alloc_order[3] = 13; ++ reg_alloc_order[4] = 14; ++ reg_alloc_order[5] = 15; ++ reg_alloc_order[6] = 1; ++ reg_alloc_order[7] = 0; ++ reg_alloc_order[8] = 4; ++ reg_alloc_order[9] = 5; ++ reg_alloc_order[10] = 6; ++ reg_alloc_order[11] = 7; ++ reg_alloc_order[12] = 8; ++ reg_alloc_order[13] = 9; ++ reg_alloc_order[14] = 10; ++ reg_alloc_order[15] = 11; ++ } + } + if (TARGET_SIMD_SET) + { +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0048-ARC-Save-restore-blink-when-in-ISR.patch b/toolchain/gcc/patches/6.3.0/0048-ARC-Save-restore-blink-when-in-ISR.patch new file mode 100644 index 0000000..3eb5b9f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0048-ARC-Save-restore-blink-when-in-ISR.patch @@ -0,0 +1,90 @@ +From 4e94874053d1705bcafefc36d164e4e61547117d Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 21 Sep 2016 13:10:29 +0200 +Subject: [PATCH 48/89] [ARC] Save/restore blink when in ISR. + +gcc/ +2016-09-21 Claudiu Zissulescu + + * config/arc/arc.c (arc_epilogue_uses): BLINK should be also + restored when in interrupt. + * config/arc/arc.md (simple_return): ARCv2 rtie instruction + doesn't have delay slot. + * testsuite/gcc.target/arc/interrupt-4.c: New file. +--- + gcc/config/arc/arc.c | 10 ++++++---- + gcc/config/arc/arc.md | 7 ++++++- + gcc/testsuite/gcc.target/arc/interrupt-4.c | 15 +++++++++++++++ + 3 files changed, 27 insertions(+), 5 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-4.c + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 379b70011f2b..d3b8a6ace4b3 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -9441,9 +9441,10 @@ arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee) + Return true if REGNO should be added to the deemed uses of the epilogue. + + We use the return address +- arc_return_address_regs[arc_compute_function_type (cfun)] . +- But also, we have to make sure all the register restore instructions +- are known to be live in interrupt functions. */ ++ arc_return_address_regs[arc_compute_function_type (cfun)]. But ++ also, we have to make sure all the register restore instructions ++ are known to be live in interrupt functions, plus the blink ++ register if it is clobbered by the isr. */ + + bool + arc_epilogue_uses (int regno) +@@ -9456,7 +9457,8 @@ arc_epilogue_uses (int regno) + { + if (!fixed_regs[regno]) + return true; +- return regno == arc_return_address_regs[cfun->machine->fn_type]; ++ return ((regno == arc_return_address_regs[cfun->machine->fn_type]) ++ || (regno == RETURN_ADDR_REGNUM)); + } + else + return regno == RETURN_ADDR_REGNUM; +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 2b239d7268f5..c8924bcaf1d6 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -4766,7 +4766,12 @@ + output_asm_insn (\"j%!%* [%0]%&\", ®); + return \"\"; + } +- [(set_attr "type" "return") ++ [(set (attr "type") ++ (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)") ++ (symbol_ref "ARC_FUNCTION_ILINK1")) ++ (match_test "TARGET_V2")) ++ (const_string "brcc_no_delay_slot")] ++ (const_string "return"))) + ; predicable won't help here since the canonical rtl looks different + ; for branches. + (set (attr "cond") +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-4.c b/gcc/testsuite/gcc.target/arc/interrupt-4.c +new file mode 100644 +index 000000000000..ea6596eb1283 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-4.c +@@ -0,0 +1,15 @@ ++#if defined (__ARCHS__) || defined (__ARCEM__) ++#define RILINK "ilink" ++#else ++#define RILINK "ilink1" ++#endif ++ ++extern int gpio_int; ++extern int read_reg (int); ++ ++void __attribute__ ((interrupt(RILINK))) ++isr_handler (void) ++{ ++ gpio_int = read_reg (1); ++} ++/* { dg-final { scan-assembler-times "blink" 2 } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0049-ARC-Fix-detection-of-long-immediate-for-load-store-o.patch b/toolchain/gcc/patches/6.3.0/0049-ARC-Fix-detection-of-long-immediate-for-load-store-o.patch new file mode 100644 index 0000000..7d77166 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0049-ARC-Fix-detection-of-long-immediate-for-load-store-o.patch @@ -0,0 +1,51 @@ +From 7bd136a42fb4ea8d3188ce80e64d348e359fea11 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 21 Sep 2016 14:59:06 +0200 +Subject: [PATCH 49/89] [ARC] Fix detection of long immediate for load/store + operands. + +ARC can use scaled offsets when loading (i.e. ld.as rA,[base, +offset]). Where base and offset can be a register or an immediate +operand. The scaling only applies on the offset part of the +instruction. The compiler can accept an address like this: + +(plus:SI (mult:SI (reg:SI 2 r2 [orig:596 _2129 ] [596]) + (const_int 4 [0x4])) + (const_int 60 [0x3c])) + +Hence, to emit this instruction we place the (const_int 60) into base +and the register into offset to take advantage of the scaled offset +facility of the load instruction. As a result the length of the load +instruction is 8 bytes. However, the long_immediate_loadstore_operand +predicate used for calculating the length attribute doesn't recognize +this address and returns a wrong decision leading to a wrong length +computation for a load instruction using the above address. + +gcc/ +2016-09-21 Claudiu Zissulescu + + * config/arc/predicates.md (long_immediate_loadstore_operand): + Consider scaled addresses cases. +--- + gcc/config/arc/predicates.md | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index f85f931d4601..7824f7234d7d 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -148,6 +148,11 @@ + { + rtx x = XEXP (op, 1); + ++ if ((GET_CODE (XEXP (op, 0)) == MULT) ++ && REG_P (XEXP (XEXP (op, 0), 0)) ++ && CONSTANT_P (x)) ++ return 1; ++ + if (GET_CODE (x) == CONST) + { + x = XEXP (x, 0); +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0050-ARC-Disable-TP-register-when-building-for-bare-metal.patch b/toolchain/gcc/patches/6.3.0/0050-ARC-Disable-TP-register-when-building-for-bare-metal.patch new file mode 100644 index 0000000..a56804f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0050-ARC-Disable-TP-register-when-building-for-bare-metal.patch @@ -0,0 +1,58 @@ +From 502d5bb134a0a78ec5fb482910bca6b7d0d10e41 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 29 Sep 2016 12:31:05 +0200 +Subject: [PATCH 50/89] [ARC] Disable TP register when building for bare metal. + +gcc/ +2016-09-29 Claudiu Zissulescu + + * config/arc/elf.h (ARGET_ARC_TP_REGNO_DEFAULT): Define. + * config/arc/linux.h (ARGET_ARC_TP_REGNO_DEFAULT): Likewise. + * config/arc/arc.opt (mtp-regno): Use ARGET_ARC_TP_REGNO_DEFAULT. +--- + gcc/config/arc/arc.opt | 2 +- + gcc/config/arc/elf.h | 5 +++++ + gcc/config/arc/linux.h | 4 ++++ + 3 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index d8b26102d469..e96b864413f4 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -406,7 +406,7 @@ EnumValue + Enum(arc_fpu) String(fpud_all) Value(FPU_FPUD_ALL) + + mtp-regno= +-Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(25) ++Target RejectNegative Joined UInteger Var(arc_tp_regno) Init(TARGET_ARC_TP_REGNO_DEFAULT) + Specify thread pointer register number. + + mtp-regno=none +diff --git a/gcc/config/arc/elf.h b/gcc/config/arc/elf.h +index 96565e53115e..f4bda99030c8 100644 +--- a/gcc/config/arc/elf.h ++++ b/gcc/config/arc/elf.h +@@ -53,3 +53,8 @@ along with GCC; see the file COPYING3. If not see + # define MULTILIB_DEFAULTS { "mcpu=" ARC_MULTILIB_CPU_DEFAULT } + # endif + #endif ++ ++/* Bare-metal toolchains are not having a thread pointer register ++ set. */ ++#undef TARGET_ARC_TP_REGNO_DEFAULT ++#define TARGET_ARC_TP_REGNO_DEFAULT -1 +diff --git a/gcc/config/arc/linux.h b/gcc/config/arc/linux.h +index e4a881fa940d..402454937d7a 100644 +--- a/gcc/config/arc/linux.h ++++ b/gcc/config/arc/linux.h +@@ -74,3 +74,7 @@ along with GCC; see the file COPYING3. If not see + /* We do not have any MULTILIB_OPTIONS specified, so there are no + MULTILIB_DEFAULTS. */ + #undef MULTILIB_DEFAULTS ++ ++/* Linux toolchains are using r25 as TLS register. */ ++#undef TARGET_ARC_TP_REGNO_DEFAULT ++#define TARGET_ARC_TP_REGNO_DEFAULT 25 +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0051-ARC-Fix-divdf3-emulation-for-arcem.patch b/toolchain/gcc/patches/6.3.0/0051-ARC-Fix-divdf3-emulation-for-arcem.patch new file mode 100644 index 0000000..5befd2a --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0051-ARC-Fix-divdf3-emulation-for-arcem.patch @@ -0,0 +1,53 @@ +From e2e4e4e5197b73743f526be8e1194e2e95ae4af0 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 29 Sep 2016 16:02:28 +0200 +Subject: [PATCH 51/89] [ARC] Fix divdf3 emulation for arcem. + +libgcc/ +2016-09-29 Claudiu Zissulescu + + * config/arc/ieee-754/divdf3.S (__divdf3): Use __ARCEM__. +--- + libgcc/config/arc/ieee-754/divdf3.S | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/libgcc/config/arc/ieee-754/divdf3.S b/libgcc/config/arc/ieee-754/divdf3.S +index 4e702dff42c5..525c2d22aa1d 100644 +--- a/libgcc/config/arc/ieee-754/divdf3.S ++++ b/libgcc/config/arc/ieee-754/divdf3.S +@@ -189,13 +189,13 @@ __divdf3: + asl r8,DBL1H,12 + lsr r12,DBL1L,20 + lsr r4,r8,26 +-#ifdef __HS__ ++#if defined (__ARCHS__) || defined (__ARCEM__) + add3 r10,pcl,60 ; (.Ldivtab-.) >> 3 + #else + add3 r10,pcl,59 ; (.Ldivtab-.) >> 3 + #endif + ld.as r4,[r10,r4] +-#ifdef __HS__ ++#if defined (__ARCHS__) || defined (__ARCEM__) + ld.as r9,[pcl,182]; [pcl,(-((.-.L7ff00000) >> 2))] ; 0x7ff00000 + #else + ld.as r9,[pcl,180]; [pcl,(-((.-.L7ff00000) >> 2))] ; 0x7ff00000 +@@ -299,14 +299,14 @@ __divdf3: + rsub r7,r6,5 + asr r10,r12,28 + bmsk r4,r12,27 +-#ifdef __HS__ ++#if defined (__ARCHS__) || defined (__ARCEM__) + min r7, r7, 31 + asr DBL0L, r4, r7 + #else + asrs DBL0L,r4,r7 + #endif + add DBL1H,r11,r10 +-#ifdef __HS__ ++#if defined (__ARCHS__) || defined (__ARCEM__) + abs.f r10, r4 + sub.mi r10, r10, 1 + #endif +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0052-ARC-Automatic-context-save-restore-for-regular-inter.patch b/toolchain/gcc/patches/6.3.0/0052-ARC-Automatic-context-save-restore-for-regular-inter.patch new file mode 100644 index 0000000..a8e00da --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0052-ARC-Automatic-context-save-restore-for-regular-inter.patch @@ -0,0 +1,721 @@ +From 34adbf7ef266a3f94549414e050fdf48a33006b5 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 4 Oct 2016 13:00:51 +0200 +Subject: [PATCH 52/89] [ARC] Automatic context save/restore for regular + interrupts. + +The AUX_IRQ_CTRL register controls the behavior of automated register +save and restore or prologue and epilogue sequences during a non-fast +interrupt entry and exit, and context save and restore instructions. + +A user passes to the compiler the configuration of the AUX_IRQ_CTRL +register via mirq-ctrl-saved option. This option, specifies +gneral-purposes registers that the processor saves/restores on +interrupt entry and exit, and it is only valid for ARC EM and ARC HS +cores. + +gcc/ +2016-10-03 Claudiu Zissulescu + + * config/arc/arc.c (irq_ctrl_saved): New variable. + (ARC_AUTOBLINK_IRQ_P): Define. + (ARC_AUTOFP_IRQ_P): Likewise. + (ARC_AUTO_IRQ_P): Likewise. + (irq_range): New function. + (arc_must_save_register): Likewise. + (arc_must_save_return_addr): Likewise. + (arc_dwarf_emit_irq_save_regs): Likewise. + (arc_override_options): Handle deferred options. + (MUST_SAVE_REGISTER): Deleted, replaced by arc_must_save_register. + (MUST_SAVE_RETURN_ADDR): Deleted, replaced by + arc_must_save_return_addr. + (arc_compute_frame_size): Handle automated save and restore of + registers. + (arc_expand_prologue): Likewise. + (arc_expand_epilogue): Likewise. + * config/arc/arc.md (stack_irq_dwarf): New unspec instruction. + * config/arc/arc.opt (mirq-ctrl-saved): New option. + * doc/invoke.texi (mirq-ctrl-saved): Document option. + * testsuite/gcc.target/arc/interrupt-5.c: Newfile. + * testsuite/gcc.target/arc/interrupt-6.c: Likewise. + * testsuite/gcc.target/arc/interrupt-7.c: Likewise. + * testsuite/gcc.target/arc/interrupt-8.c: Likewise. + * testsuite/gcc.target/arc/interrupt-9.c: Likewise. +--- + gcc/config/arc/arc.c | 320 ++++++++++++++++++++++++++--- + gcc/config/arc/arc.md | 8 + + gcc/config/arc/arc.opt | 4 + + gcc/doc/invoke.texi | 10 + + gcc/testsuite/gcc.target/arc/interrupt-5.c | 19 ++ + gcc/testsuite/gcc.target/arc/interrupt-6.c | 22 ++ + gcc/testsuite/gcc.target/arc/interrupt-7.c | 16 ++ + gcc/testsuite/gcc.target/arc/interrupt-8.c | 27 +++ + gcc/testsuite/gcc.target/arc/interrupt-9.c | 17 ++ + 9 files changed, 412 insertions(+), 31 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-5.c + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-6.c + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-7.c + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-8.c + create mode 100644 gcc/testsuite/gcc.target/arc/interrupt-9.c + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index d3b8a6ace4b3..bcb3083d3ace 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -62,6 +62,7 @@ along with GCC; see the file COPYING3. If not see + #include "builtins.h" + #include "rtl-iter.h" + #include "alias.h" ++#include "opts.h" + + /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */ + static char arc_cpu_name[10] = ""; +@@ -117,6 +118,29 @@ struct GTY (()) arc_ccfsm + int target_label; + }; + ++/* Status of the IRQ_CTRL_AUX register. */ ++typedef struct irq_ctrl_saved_t ++{ ++ short irq_save_last_reg; /* Last register number used by ++ IRQ_CTRL_SAVED aux_reg. */ ++ bool irq_save_blink; /* True if BLINK is automatically ++ saved. */ ++ bool irq_save_lpcount; /* True if LPCOUNT is automatically ++ saved. */ ++} irq_ctrl_saved_t; ++static irq_ctrl_saved_t irq_ctrl_saved; ++ ++#define ARC_AUTOBLINK_IRQ_P(FNTYPE) \ ++ (ARC_INTERRUPT_P (FNTYPE) && irq_ctrl_saved.irq_save_blink) ++ ++#define ARC_AUTOFP_IRQ_P(FNTYPE) \ ++ (ARC_INTERRUPT_P (FNTYPE) && (irq_ctrl_saved.irq_save_last_reg > 26)) ++ ++#define ARC_AUTO_IRQ_P(FNTYPE) \ ++ (ARC_INTERRUPT_P (FNTYPE) \ ++ && (irq_ctrl_saved.irq_save_blink \ ++ || (irq_ctrl_saved.irq_save_last_reg >= 0))) ++ + #define arc_ccfsm_current cfun->machine->ccfsm_current + + #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \ +@@ -789,11 +813,110 @@ arc_init (void) + } + } + ++/* Parse -mirq-ctrl-saved= option string. Registers may be specified ++ individually, or as ranges such as "r0-r3". Registers accepted are ++ r0 through r31 and lp_count. Registers and ranges must be ++ comma-separated. */ ++ ++static void ++irq_range (const char *cstr) ++{ ++ int i, first, last, blink, lpcount, xreg; ++ char *str, *dash, *comma; ++ ++ i = strlen (cstr); ++ str = (char *) alloca (i + 1); ++ memcpy (str, cstr, i + 1); ++ blink = -1; ++ lpcount = -1; ++ ++ dash = strchr (str, '-'); ++ if (!dash) ++ { ++ warning (0, "value of -mirq-ctrl-saved must have form R0-REGx"); ++ return; ++ } ++ *dash = '\0'; ++ ++ comma = strchr (dash + 1, ','); ++ if (comma) ++ *comma = '\0'; ++ ++ first = decode_reg_name (str); ++ if (first != 0) ++ { ++ warning (0, "first register must be R0"); ++ return; ++ } ++ ++ /* At this moment we do not have the register names initialized ++ accordingly. */ ++ if (!strcmp (dash + 1, "ilink")) ++ last = 29; ++ else ++ last = decode_reg_name (dash + 1); ++ ++ if (last < 0) ++ { ++ warning (0, "unknown register name: %s", dash + 1); ++ return; ++ } ++ ++ if (!(last & 0x01)) ++ { ++ warning (0, "last register name %s must be an odd register", dash + 1); ++ return; ++ } ++ ++ *dash = '-'; ++ ++ if (first > last) ++ { ++ warning (0, "%s-%s is an empty range", str, dash + 1); ++ return; ++ } ++ ++ while (comma) ++ { ++ *comma = ','; ++ str = comma + 1; ++ ++ comma = strchr (str, ','); ++ if (comma) ++ *comma = '\0'; ++ ++ xreg = decode_reg_name (str); ++ switch (xreg) ++ { ++ case 31: ++ blink = 31; ++ break; ++ ++ case 60: ++ lpcount = 60; ++ break; ++ ++ default: ++ warning (0, "unknown register name: %s", str); ++ return; ++ } ++ } ++ ++ irq_ctrl_saved.irq_save_last_reg = last; ++ irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31); ++ irq_ctrl_saved.irq_save_lpcount = (lpcount == 60); ++} ++ + /* Check ARC options, generate derived target attributes. */ + + static void + arc_override_options (void) + { ++ unsigned int i; ++ cl_deferred_option *opt; ++ vec *vopt ++ = (vec *) arc_deferred_options; ++ + if (arc_cpu == PROCESSOR_NONE) + arc_cpu = TARGET_CPU_DEFAULT; + +@@ -827,6 +950,28 @@ arc_override_options (void) + gcc_unreachable (); + } + ++ irq_ctrl_saved.irq_save_last_reg = -1; ++ irq_ctrl_saved.irq_save_blink = false; ++ irq_ctrl_saved.irq_save_lpcount = false; ++ ++ /* Handle the deferred options. */ ++ if (vopt) ++ FOR_EACH_VEC_ELT (*vopt, i, opt) ++ { ++ switch (opt->opt_index) ++ { ++ case OPT_mirq_ctrl_saved_: ++ if (TARGET_V2) ++ irq_range (opt->arg); ++ else ++ warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors"); ++ break; ++ ++ default: ++ gcc_unreachable(); ++ } ++ } ++ + /* Set cpu flags accordingly to architecture/selected cpu. The cpu + specific flags are set in arc-common.c. The architecture forces + the default hardware configurations in, regardless what command +@@ -2219,15 +2364,43 @@ arc_compute_function_type (struct function *fun) + code like this. The number of frames that use __builtin_eh_return + is pretty low, so optimising them is not critical right now. */ + +-#define MUST_SAVE_REGISTER(regno, interrupt_p) \ +- (((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \ +- && (df_regs_ever_live_p (regno) \ +- && (!call_used_regs[regno] || interrupt_p))) \ +- || (flag_pic && crtl->uses_pic_offset_table \ +- && regno == PIC_OFFSET_TABLE_REGNUM) \ +- || (crtl->calls_eh_return && (regno > 2 && regno < 27))) ++static bool ++arc_must_save_register (int regno, struct function *func) ++{ ++ enum arc_function_type fn_type = arc_compute_function_type (func); ++ bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno) ++ && ARC_INTERRUPT_P (fn_type)); ++ ++ if ((regno) != RETURN_ADDR_REGNUM ++ && (regno) != FRAME_POINTER_REGNUM ++ && df_regs_ever_live_p (regno) ++ && (!call_used_regs[regno] ++ || ARC_INTERRUPT_P (fn_type)) ++ /* Do not emit code for auto saved regs. */ ++ && !irq_auto_save_p) ++ return true; ++ ++ if (flag_pic && crtl->uses_pic_offset_table ++ && regno == PIC_OFFSET_TABLE_REGNUM) ++ return true; ++ ++ if (crtl->calls_eh_return && (regno > 2 && regno < 27)) ++ return true; ++ ++ return false; ++} ++ ++/* Return true if the return address must be saved in the current function, ++ otherwise return false. */ ++ ++static bool ++arc_must_save_return_addr (struct function *func) ++{ ++ if (func->machine->frame_info.save_return_addr) ++ return true; + +-#define MUST_SAVE_RETURN_ADDR (cfun->machine->frame_info.save_return_addr) ++ return false; ++} + + /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as + FRAME_POINTER_NEEDED will not be true until the IRA (Integrated +@@ -2245,9 +2418,9 @@ arc_compute_function_type (struct function *fun) + + As the frame pointer is handled as a special case in our prologue + and epilogue code it must not be saved and restored using the +- MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC +- believes that the function is not using a frame pointer and that +- the value in the fp register is the frame pointer, while the ++ arc_must_save_register mechanism otherwise we run into issues where ++ GCC believes that the function is not using a frame pointer and ++ that the value in the fp register is the frame pointer, while the + prologue and epilogue are busy saving and restoring the fp + register. This issue is fixed in this commit too. + +@@ -2317,8 +2490,6 @@ arc_compute_frame_size (void) + unsigned int total_size, var_size, args_size, pretend_size, extra_size; + unsigned int reg_size, reg_offset; + unsigned int gmask; +- enum arc_function_type fn_type; +- int interrupt_p; + struct arc_frame_info *frame_info; + int size; + +@@ -2343,15 +2514,13 @@ arc_compute_frame_size (void) + + reg_size = 0; + gmask = 0; +- fn_type = arc_compute_function_type (cfun); +- interrupt_p = ARC_INTERRUPT_P (fn_type); + + for (regno = 0; regno <= 31; regno++) + { +- if (MUST_SAVE_REGISTER (regno, interrupt_p)) ++ if (arc_must_save_register (regno, cfun)) + { + reg_size += UNITS_PER_WORD; +- gmask |= 1 << regno; ++ gmask |= 1L << regno; + } + } + +@@ -2384,7 +2553,7 @@ arc_compute_frame_size (void) + } + + extra_size = 0; +- if (MUST_SAVE_RETURN_ADDR) ++ if (arc_must_save_return_addr (cfun)) + extra_size = 4; + if (arc_frame_pointer_needed ()) + extra_size += 4; +@@ -2606,6 +2775,77 @@ arc_save_restore (rtx base_reg, + int arc_return_address_regs[4] + = {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM}; + ++ ++/* Build dwarf information when the context is saved via AUX_IRQ_CTRL ++ mechanism. */ ++ ++static void ++arc_dwarf_emit_irq_save_regs (void) ++{ ++ rtx tmp, par, insn, reg; ++ int i, offset, j; ++ ++ par = gen_rtx_SEQUENCE (VOIDmode, ++ rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1 ++ + irq_ctrl_saved.irq_save_blink ++ + irq_ctrl_saved.irq_save_lpcount ++ + 1)); ++ ++ /* Build the stack adjustment note for unwind info. */ ++ j = 0; ++ offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1 ++ + irq_ctrl_saved.irq_save_blink ++ + irq_ctrl_saved.irq_save_lpcount); ++ tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset); ++ tmp = gen_rtx_SET (stack_pointer_rtx, tmp); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (par, 0, j++) = tmp; ++ ++ offset -= UNITS_PER_WORD; ++ ++ /* 1st goes LP_COUNT. */ ++ if (irq_ctrl_saved.irq_save_lpcount) ++ { ++ reg = gen_rtx_REG (SImode, 60); ++ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); ++ tmp = gen_frame_mem (SImode, tmp); ++ tmp = gen_rtx_SET (tmp, reg); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (par, 0, j++) = tmp; ++ offset -= UNITS_PER_WORD; ++ } ++ ++ /* 2nd goes BLINK. */ ++ if (irq_ctrl_saved.irq_save_blink) ++ { ++ reg = gen_rtx_REG (SImode, 31); ++ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); ++ tmp = gen_frame_mem (SImode, tmp); ++ tmp = gen_rtx_SET (tmp, reg); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (par, 0, j++) = tmp; ++ offset -= UNITS_PER_WORD; ++ } ++ ++ /* Build the parallel of the remaining registers recorded as saved ++ for unwind. */ ++ for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--) ++ { ++ reg = gen_rtx_REG (SImode, i); ++ tmp = plus_constant (Pmode, stack_pointer_rtx, offset); ++ tmp = gen_frame_mem (SImode, tmp); ++ tmp = gen_rtx_SET (tmp, reg); ++ RTX_FRAME_RELATED_P (tmp) = 1; ++ XVECEXP (par, 0, j++) = tmp; ++ offset -= UNITS_PER_WORD; ++ } ++ ++ /* Dummy insn used to anchor the dwarf info. */ ++ insn = emit_insn (gen_stack_irq_dwarf()); ++ add_reg_note (insn, REG_FRAME_RELATED_EXPR, par); ++ RTX_FRAME_RELATED_P (insn) = 1; ++} ++ + /* Set up the stack and frame pointer (if desired) for the function. */ + + void +@@ -2619,6 +2859,7 @@ arc_expand_prologue (void) + Change the stack layout so that we rather store a high register with the + PRE_MODIFY, thus enabling more short insn generation.) */ + int first_offset = 0; ++ enum arc_function_type fn_type = arc_compute_function_type (cfun); + + /* Compute total frame size. */ + size = arc_compute_frame_size (); +@@ -2642,30 +2883,41 @@ arc_expand_prologue (void) + frame_size_to_allocate -= cfun->machine->frame_info.pretend_size; + } + ++ /* IRQ using automatic save mechanism will save the register before ++ anything we do. */ ++ if (ARC_AUTO_IRQ_P (fn_type)) ++ { ++ arc_dwarf_emit_irq_save_regs (); ++ } ++ + /* The home-grown ABI says link register is saved first. */ +- if (MUST_SAVE_RETURN_ADDR) ++ if (arc_must_save_return_addr (cfun) ++ && !ARC_AUTOBLINK_IRQ_P (fn_type)) + { + rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM); +- rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode, stack_pointer_rtx)); ++ rtx mem = gen_frame_mem (Pmode, ++ gen_rtx_PRE_DEC (Pmode, ++ stack_pointer_rtx)); + + frame_move_inc (mem, ra, stack_pointer_rtx, 0); + frame_size_to_allocate -= UNITS_PER_WORD; +- +- } /* MUST_SAVE_RETURN_ADDR */ ++ } + + /* Save any needed call-saved regs (and call-used if this is an + interrupt handler) for ARCompact ISA. */ + if (cfun->machine->frame_info.reg_size) + { + first_offset = -cfun->machine->frame_info.reg_size; ++ + /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */ + arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset); + frame_size_to_allocate -= cfun->machine->frame_info.reg_size; + } + +- +- /* Save frame pointer if needed. */ +- if (arc_frame_pointer_needed ()) ++ /* Save frame pointer if needed. First save the FP on stack, if not ++ autosaved. */ ++ if (arc_frame_pointer_needed () ++ && !ARC_AUTOFP_IRQ_P (fn_type)) + { + rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx, + GEN_INT (-UNITS_PER_WORD + first_offset)); +@@ -2675,6 +2927,11 @@ arc_expand_prologue (void) + frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0); + frame_size_to_allocate -= UNITS_PER_WORD; + first_offset = 0; ++ } ++ ++ /* Emit mov fp,sp. */ ++ if (arc_frame_pointer_needed ()) ++ { + frame_move (frame_pointer_rtx, stack_pointer_rtx); + } + +@@ -2743,7 +3000,8 @@ arc_expand_epilogue (int sibcall_p) + + + /* Restore any saved registers. */ +- if (arc_frame_pointer_needed ()) ++ if (arc_frame_pointer_needed () ++ && !ARC_AUTOFP_IRQ_P (fn_type)) + { + rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx); + +@@ -2781,14 +3039,15 @@ arc_expand_epilogue (int sibcall_p) + : satisfies_constraint_C2a (GEN_INT (first_offset)))) + /* Also do this if we have both gprs and return + address to restore, and they both would need a LIMM. */ +- || (MUST_SAVE_RETURN_ADDR +- && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2) +- && cfun->machine->frame_info.gmask)) ++ || (arc_must_save_return_addr (cfun) ++ && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2) ++ && cfun->machine->frame_info.gmask)) + { + frame_stack_add (first_offset); + first_offset = 0; + } +- if (MUST_SAVE_RETURN_ADDR) ++ if (arc_must_save_return_addr (cfun) ++ && !ARC_AUTOBLINK_IRQ_P (fn_type)) + { + rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM); + int ra_offs = cfun->machine->frame_info.reg_size + first_offset; +@@ -2853,7 +3112,6 @@ arc_expand_epilogue (int sibcall_p) + & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset); + } + +- + /* The rest of this function does the following: + ARCompact : handle epilogue_delay, restore sp (phase-2), return + */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index c8924bcaf1d6..30cc237ec84f 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -6194,6 +6194,14 @@ + (set_attr "iscompact" "maybe,false") + (set_attr "predicable" "no,no")]) + ++;; Dummy pattern used as a place holder for automatically saved ++;; registers. ++(define_insn "stack_irq_dwarf" ++ [(unspec_volatile [(const_int 1)] VUNSPEC_ARC_STACK_IRQ)] ++ "" ++ "" ++ [(set_attr "length" "0")]) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index e96b864413f4..dde2d49cce0b 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -426,3 +426,7 @@ Enable unaligned word and halfword accesses to packed data. + + TargetVariable + unsigned int arc_seen_options = 0 ++ ++mirq-ctrl-saved= ++Target RejectNegative Joined Var(arc_deferred_options) Defer ++Specifies the registers that the processor saves on an interrupt entry and exit. +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index c4d574660c1a..f3436e006511 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -591,6 +591,7 @@ Objective-C and Objective-C++ Dialects}. + -mnorm -mspfp -mspfp-compact -mspfp-fast -msimd -msoft-float -mswap @gol + -mcrc -mdsp-packa -mdvbf -mlock -mmac-d16 -mmac-24 -mrtsc -mswape @gol + -mtelephony -mxy -misize -mannotate-align -marclinux -marclinux_prof @gol ++-mirq-ctrl-saved @gol + -mlong-calls -mmedium-calls -msdata @gol + -mvolatile-cache -mtp-regno=@var{regno} @gol + -malign-call -mauto-modify-reg -mbbit-peephole -mno-brcc @gol +@@ -13535,6 +13536,15 @@ hardware extensions. Not available for ARC EM@. + + @end table + ++@item -mirq-ctrl-saved="REGS" ++@opindex mirq-ctrl-saved ++Specifies gneral-purposes registers that the processor saves/restores ++on interrupt entry and exit. Permited values: r0-r29, fp, blink, and ++lp_count. Registers needs to be specified as ranges such as "r0-r3". ++A register range always starts with r0. Registers blink and lp_count ++can be specified individually. Only valid for ARC EM and ARC HS ++cores. ++ + @end table + + The following options are passed through to the assembler, and also +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-5.c b/gcc/testsuite/gcc.target/arc/interrupt-5.c +new file mode 100644 +index 000000000000..ee01d760d90b +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-5.c +@@ -0,0 +1,19 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "Not available for ARCv1" { arc700 || arc6xx } } */ ++/* { dg-options "-O2 -mirq-ctrl-saved=r0-r3,blink" } */ ++ ++/* Check if the registers R0-R3,blink are automatically saved. */ ++ ++extern int bar (void *); ++ ++void __attribute__ ((interrupt("ilink"))) ++foo(void) ++{ ++ bar (0); ++ __asm__ volatile ( "" : : : "r0","r1","r2","r3"); ++} ++/* { dg-final { scan-assembler-not "st.*r0,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r1,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r2,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r3,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "push_s blink" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-6.c b/gcc/testsuite/gcc.target/arc/interrupt-6.c +new file mode 100644 +index 000000000000..509ff3021248 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-6.c +@@ -0,0 +1,22 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "Not available for ARCv1" { arc700 || arc6xx } } */ ++/* { dg-options "-O2 -mirq-ctrl-saved=r0-ilink" } */ ++ ++#include ++ ++/* Check if ilink is recognized. Check how FP and BLINK are saved. ++ BLINK is saved last on the stack because the IRQ autosave will do ++ first r0-ilink. To avoid this ABI exception, one needs to autosave ++ always blink when using the IRQ autosave feature. */ ++ ++extern int bar (void *); ++ ++void __attribute__ ((interrupt("ilink"))) ++foo(void) ++{ ++ int *p = alloca (10); ++ bar (p); ++} ++/* { dg-final { scan-assembler-not ".*fp,\\\[sp" } } */ ++/* { dg-final { scan-assembler "ld.*blink,\\\[sp\\\]" } } */ ++/* { dg-final { scan-assembler "push_s.*blink" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-7.c b/gcc/testsuite/gcc.target/arc/interrupt-7.c +new file mode 100644 +index 000000000000..547dfd380bb8 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-7.c +@@ -0,0 +1,16 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "Not available for ARCv1" { arc700 || arc6xx } } */ ++/* { dg-options "-O2 -mirq-ctrl-saved=r0-r17,blink" } */ ++ ++/* Check if the registers R0-R17,blink are automatically saved. */ ++ ++void __attribute__ ((interrupt("ilink"))) ++foo(void) ++{ ++ __asm__ volatile ( "" : : : "r13","r14","r15","r16"); ++} ++/* { dg-final { scan-assembler-not "st.*r13,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r14,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r15,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r16,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "push_s blink" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-8.c b/gcc/testsuite/gcc.target/arc/interrupt-8.c +new file mode 100644 +index 000000000000..60fd87b43951 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-8.c +@@ -0,0 +1,27 @@ ++/* { dg-do compile } */ ++/* { dg-skip-if "Not available for ARCv1" { arc700 || arc6xx } } */ ++/* { dg-options "-O2 -mirq-ctrl-saved=r0-r17" } */ ++ ++/* Check if the registers R0-R17 are automatically saved. GP is saved ++ by the compiler. */ ++ ++int a; ++ ++void __attribute__ ((interrupt("ilink"))) ++foo(void) ++{ ++ __asm__ volatile ( "" : : : "r0","r1","r2","r3"); ++ __asm__ volatile ( "" : : : "r13","r14","r15","r16"); ++ a++; ++} ++/* { dg-final { scan-assembler-not "st.*r13,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r14,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r15,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r16,\\\[sp" } } */ ++/* { dg-final { scan-assembler "st.*gp,\\\[sp,-4\\\]" } } */ ++/* { dg-final { scan-assembler "ld.*gp,\\\[sp\\\]" } } */ ++/* { dg-final { scan-assembler-not "st.*r0,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r1,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r2,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "st.*r3,\\\[sp" } } */ ++/* { dg-final { scan-assembler "rtie" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/interrupt-9.c b/gcc/testsuite/gcc.target/arc/interrupt-9.c +new file mode 100644 +index 000000000000..4547fef8410f +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/interrupt-9.c +@@ -0,0 +1,17 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O0 -mirq-ctrl-saved=r0-fp" } */ ++ ++/* Check if we get the move operation between fp and sp. */ ++ ++void __attribute__ ((interrupt("ilink"))) ++handler1 (void) ++{ ++ asm ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9"); ++} ++/* { dg-final { scan-assembler "mov.*fp,sp" } } */ ++/* { dg-final { scan-assembler-not ".*fp,\\\[sp" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0053-ARC-Fast-interrupts-support.patch b/toolchain/gcc/patches/6.3.0/0053-ARC-Fast-interrupts-support.patch new file mode 100644 index 0000000..df53ef5 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0053-ARC-Fast-interrupts-support.patch @@ -0,0 +1,575 @@ +From d44aad6d17172957f9dd8dd63bca85a96f873765 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 4 Oct 2016 17:34:51 +0200 +Subject: [PATCH 53/89] [ARC] Fast interrupts support. + +When a processor enters a fast interrupts handler, and duplicate +register banks are configured, the processor saves the user context by +saving the registers in the main register bank to these additional +registers in the duplicate register bank. In this fast interrupt +context, when you specify the rgf_banked_regs option,the compiler does +not save the registers duplicated in the additional register bank are +not saved. + +gcc/ +2016-10-04 Claudiu Zissulescu + Andrew Burgess + + * config/arc/arc.c (ARC_AUTOBLINK_IRQ_P): Consider fast interrupts + case also. + (ARC_AUTOFP_IRQ_P): Likewise. + (ARC_AUTO_IRQ_P): Likewise. + (rgf_banked_register_count): New variable. + (parse_mrgf_banked_regs_option): New function. + (arc_override_options): Handle rgf_banked_regs option. + (arc_handle_interrupt_attribute): Add firq option. + (arc_compute_function_type): Return fast irq type when required. + (arc_must_save_register): Handle fast interrupts. + (arc_expand_prologue): Do not emit dwarf info for fast interrupts. + (arc_return_address_regs): Update. + * config/arc/arc.h (arc_return_address_regs): Update. + (arc_function_type): Add fast interrupt type. + (ARC_INTERRUPT_P): Update. + (RC_FAST_INTERRUPT_P): Define. + * config/arc/arc.md (simple_return): Update for fast interrupts. + (p_return_i): Likewise. + * config/arc/arc.opt (mrgf-banked-regs): New option. + * doc/invoke.texi (mrgf-banked-regs): Document. + * testsuite/gcc.target/arc/firq-1.c: New file. + * testsuite/gcc.target/arc/firq-2.c: Likewise. + * testsuite/gcc.target/arc/firq-3.c: Likewise. + * testsuite/gcc.target/arc/firq-4.c: Likewise. + * testsuite/gcc.target/arc/firq-5.c: Likewise. + * testsuite/gcc.target/arc/firq-6.c: Likewise. +--- + gcc/config/arc/arc.c | 106 +++++++++++++++++++++++++++------- + gcc/config/arc/arc.h | 13 +++-- + gcc/config/arc/arc.md | 9 ++- + gcc/config/arc/arc.opt | 4 ++ + gcc/doc/invoke.texi | 14 ++++- + gcc/testsuite/gcc.target/arc/firq-1.c | 27 +++++++++ + gcc/testsuite/gcc.target/arc/firq-2.c | 31 ++++++++++ + gcc/testsuite/gcc.target/arc/firq-3.c | 40 +++++++++++++ + gcc/testsuite/gcc.target/arc/firq-4.c | 31 ++++++++++ + gcc/testsuite/gcc.target/arc/firq-5.c | 15 +++++ + gcc/testsuite/gcc.target/arc/firq-6.c | 21 +++++++ + 11 files changed, 280 insertions(+), 31 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/firq-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/firq-2.c + create mode 100644 gcc/testsuite/gcc.target/arc/firq-3.c + create mode 100644 gcc/testsuite/gcc.target/arc/firq-4.c + create mode 100644 gcc/testsuite/gcc.target/arc/firq-5.c + create mode 100644 gcc/testsuite/gcc.target/arc/firq-6.c + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index bcb3083d3ace..282e7d45aa4b 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -131,16 +131,25 @@ typedef struct irq_ctrl_saved_t + static irq_ctrl_saved_t irq_ctrl_saved; + + #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \ +- (ARC_INTERRUPT_P (FNTYPE) && irq_ctrl_saved.irq_save_blink) +- +-#define ARC_AUTOFP_IRQ_P(FNTYPE) \ +- (ARC_INTERRUPT_P (FNTYPE) && (irq_ctrl_saved.irq_save_last_reg > 26)) +- +-#define ARC_AUTO_IRQ_P(FNTYPE) \ +- (ARC_INTERRUPT_P (FNTYPE) \ +- && (irq_ctrl_saved.irq_save_blink \ ++ ((ARC_INTERRUPT_P (FNTYPE) \ ++ && irq_ctrl_saved.irq_save_blink) \ ++ || (ARC_FAST_INTERRUPT_P (FNTYPE) \ ++ && rgf_banked_register_count > 8)) ++ ++#define ARC_AUTOFP_IRQ_P(FNTYPE) \ ++ ((ARC_INTERRUPT_P (FNTYPE) \ ++ && (irq_ctrl_saved.irq_save_last_reg > 26)) \ ++ || (ARC_FAST_INTERRUPT_P (FNTYPE) \ ++ && rgf_banked_register_count > 8)) ++ ++#define ARC_AUTO_IRQ_P(FNTYPE) \ ++ (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \ ++ && (irq_ctrl_saved.irq_save_blink \ + || (irq_ctrl_saved.irq_save_last_reg >= 0))) + ++/* Number of registers in second bank for FIRQ support. */ ++static int rgf_banked_register_count; ++ + #define arc_ccfsm_current cfun->machine->ccfsm_current + + #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \ +@@ -907,6 +916,27 @@ irq_range (const char *cstr) + irq_ctrl_saved.irq_save_lpcount = (lpcount == 60); + } + ++/* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4, ++ 8, 16, or 32. */ ++ ++static void ++parse_mrgf_banked_regs_option (const char *arg) ++{ ++ long int val; ++ char *end_ptr; ++ ++ errno = 0; ++ val = strtol (arg, &end_ptr, 10); ++ if (errno != 0 || *arg == '\0' || *end_ptr != '\0' ++ || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32)) ++ { ++ error ("invalid number in -mrgf-banked-regs=%s " ++ "valid values are 0, 4, 8, 16, or 32", arg); ++ return; ++ } ++ rgf_banked_register_count = (int) val; ++} ++ + /* Check ARC options, generate derived target attributes. */ + + static void +@@ -954,6 +984,8 @@ arc_override_options (void) + irq_ctrl_saved.irq_save_blink = false; + irq_ctrl_saved.irq_save_lpcount = false; + ++ rgf_banked_register_count = 0; ++ + /* Handle the deferred options. */ + if (vopt) + FOR_EACH_VEC_ELT (*vopt, i, opt) +@@ -967,6 +999,13 @@ arc_override_options (void) + warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors"); + break; + ++ case OPT_mrgf_banked_regs_: ++ if (TARGET_V2) ++ parse_mrgf_banked_regs_option (opt->arg); ++ else ++ warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors"); ++ break; ++ + default: + gcc_unreachable(); + } +@@ -1755,9 +1794,9 @@ arc_handle_interrupt_attribute (tree *, tree name, tree args, int, + name); + *no_add_attrs = true; + } +- else if (strcmp (TREE_STRING_POINTER (value), "ilink1") +- && strcmp (TREE_STRING_POINTER (value), "ilink2") +- && !TARGET_V2) ++ else if (!TARGET_V2 ++ && strcmp (TREE_STRING_POINTER (value), "ilink1") ++ && strcmp (TREE_STRING_POINTER (value), "ilink2")) + { + warning (OPT_Wattributes, + "argument of %qE attribute is not \"ilink1\" or \"ilink2\"", +@@ -1765,10 +1804,11 @@ arc_handle_interrupt_attribute (tree *, tree name, tree args, int, + *no_add_attrs = true; + } + else if (TARGET_V2 +- && strcmp (TREE_STRING_POINTER (value), "ilink")) ++ && strcmp (TREE_STRING_POINTER (value), "ilink") ++ && strcmp (TREE_STRING_POINTER (value), "firq")) + { + warning (OPT_Wattributes, +- "argument of %qE attribute is not \"ilink\"", ++ "argument of %qE attribute is not \"ilink\" or \"firq\"", + name); + *no_add_attrs = true; + } +@@ -2328,6 +2368,8 @@ arc_compute_function_type (struct function *fun) + fn_type = ARC_FUNCTION_ILINK1; + else if (!strcmp (TREE_STRING_POINTER (value), "ilink2")) + fn_type = ARC_FUNCTION_ILINK2; ++ else if (!strcmp (TREE_STRING_POINTER (value), "firq")) ++ fn_type = ARC_FUNCTION_FIRQ; + else + gcc_unreachable (); + break; +@@ -2369,7 +2411,29 @@ arc_must_save_register (int regno, struct function *func) + { + enum arc_function_type fn_type = arc_compute_function_type (func); + bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno) +- && ARC_INTERRUPT_P (fn_type)); ++ && ARC_AUTO_IRQ_P (fn_type)); ++ bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type); ++ ++ switch (rgf_banked_register_count) ++ { ++ case 4: ++ firq_auto_save_p &= (regno < 4); ++ break; ++ case 8: ++ firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16))); ++ break; ++ case 16: ++ firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16)) ++ || ((regno > 25) && (regno < 29)) ++ || ((regno > 29) && (regno < 32))); ++ break; ++ case 32: ++ firq_auto_save_p &= (regno != 29) && (regno < 32); ++ break; ++ default: ++ firq_auto_save_p = false; ++ break; ++ } + + if ((regno) != RETURN_ADDR_REGNUM + && (regno) != FRAME_POINTER_REGNUM +@@ -2377,7 +2441,8 @@ arc_must_save_register (int regno, struct function *func) + && (!call_used_regs[regno] + || ARC_INTERRUPT_P (fn_type)) + /* Do not emit code for auto saved regs. */ +- && !irq_auto_save_p) ++ && !irq_auto_save_p ++ && !firq_auto_save_p) + return true; + + if (flag_pic && crtl->uses_pic_offset_table +@@ -2771,11 +2836,6 @@ arc_save_restore (rtx base_reg, + } + } /* arc_save_restore */ + +- +-int arc_return_address_regs[4] +- = {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM}; +- +- + /* Build dwarf information when the context is saved via AUX_IRQ_CTRL + mechanism. */ + +@@ -2885,7 +2945,8 @@ arc_expand_prologue (void) + + /* IRQ using automatic save mechanism will save the register before + anything we do. */ +- if (ARC_AUTO_IRQ_P (fn_type)) ++ if (ARC_AUTO_IRQ_P (fn_type) ++ && !ARC_FAST_INTERRUPT_P (fn_type)) + { + arc_dwarf_emit_irq_save_regs (); + } +@@ -9695,6 +9756,9 @@ arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee) + return true; + } + ++int arc_return_address_regs[5] = ++ {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM, ILINK1_REGNUM}; ++ + /* Implement EPILOGUE__USES. + Return true if REGNO should be added to the deemed uses of the epilogue. + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 5ca2bb5ffcd0..86bc6088fbcd 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1337,7 +1337,7 @@ do { \ + + /* To translate the return value of arc_function_type into a register number + to jump through for function return. */ +-extern int arc_return_address_regs[4]; ++extern int arc_return_address_regs[5]; + + /* Debugging information. */ + +@@ -1477,10 +1477,15 @@ enum arc_function_type { + ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL, + /* These are interrupt handlers. The name corresponds to the register + name that contains the return address. */ +- ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2 ++ ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2, ++ /* Fast interrupt is only available on ARCv2 processors. */ ++ ARC_FUNCTION_FIRQ + }; +-#define ARC_INTERRUPT_P(TYPE) \ +-((TYPE) == ARC_FUNCTION_ILINK1 || (TYPE) == ARC_FUNCTION_ILINK2) ++#define ARC_INTERRUPT_P(TYPE) \ ++ (((TYPE) == ARC_FUNCTION_ILINK1) || ((TYPE) == ARC_FUNCTION_ILINK2) \ ++ || ((TYPE) == ARC_FUNCTION_FIRQ)) ++ ++#define ARC_FAST_INTERRUPT_P(TYPE) ((TYPE) == ARC_FUNCTION_FIRQ) + + /* Compute the type of a function from its DECL. Needed for EPILOGUE_USES. */ + struct function; +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 30cc237ec84f..4306d7229437 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -4756,8 +4756,8 @@ + = gen_rtx_REG (Pmode, + arc_return_address_regs[arc_compute_function_type (cfun)]); + +- if (arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1 +- && TARGET_V2) ++ if (TARGET_V2 ++ && ARC_INTERRUPT_P (arc_compute_function_type (cfun))) + { + return \"rtie\"; + } +@@ -4767,8 +4767,7 @@ + return \"\"; + } + [(set (attr "type") +- (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)") +- (symbol_ref "ARC_FUNCTION_ILINK1")) ++ (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))") + (match_test "TARGET_V2")) + (const_string "brcc_no_delay_slot")] + (const_string "return"))) +@@ -4798,7 +4797,7 @@ + (simple_return) (pc)))] + "reload_completed + && !(TARGET_V2 +- && arc_compute_function_type (cfun) == ARC_FUNCTION_ILINK1)" ++ && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))" + { + rtx xop[2]; + xop[0] = operands[0]; +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index dde2d49cce0b..90ff4ad27f67 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -430,3 +430,7 @@ unsigned int arc_seen_options = 0 + mirq-ctrl-saved= + Target RejectNegative Joined Var(arc_deferred_options) Defer + Specifies the registers that the processor saves on an interrupt entry and exit. ++ ++mrgf-banked-regs= ++Target RejectNegative Joined Var(arc_deferred_options) Defer ++Specifies the number of registers replicated in second register bank on entry to fast interrupt. +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index f3436e006511..79ee47c2820f 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -591,7 +591,7 @@ Objective-C and Objective-C++ Dialects}. + -mnorm -mspfp -mspfp-compact -mspfp-fast -msimd -msoft-float -mswap @gol + -mcrc -mdsp-packa -mdvbf -mlock -mmac-d16 -mmac-24 -mrtsc -mswape @gol + -mtelephony -mxy -misize -mannotate-align -marclinux -marclinux_prof @gol +--mirq-ctrl-saved @gol ++-mirq-ctrl-saved -mrgf-banked-regs @gol + -mlong-calls -mmedium-calls -msdata @gol + -mvolatile-cache -mtp-regno=@var{regno} @gol + -malign-call -mauto-modify-reg -mbbit-peephole -mno-brcc @gol +@@ -13545,6 +13545,18 @@ A register range always starts with r0. Registers blink and lp_count + can be specified individually. Only valid for ARC EM and ARC HS + cores. + ++@item -mrgf-banked-regs="NUMBER" ++@opindex mrgf-banked-regs ++Specifies the number of registers replicated in second register bank ++on entry to fast interrupt. Fast interrupts are interrupts with the ++highest priority level P0. These interrupts save only PC and STATUS32 ++registers to avoid memory transactions during interrupt entry and exit ++sequences. Use this option when you are using fast interrupts in an ++ARC V2 family processor. ++ ++Permitted values are 4, 8, 16, 32 and specify the number of registers ++that are covered by the second register bank. ++ + @end table + + The following options are passed through to the assembler, and also +diff --git a/gcc/testsuite/gcc.target/arc/firq-1.c b/gcc/testsuite/gcc.target/arc/firq-1.c +new file mode 100644 +index 000000000000..87f408793dc9 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-1.c +@@ -0,0 +1,27 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O0 -mll64 -mirq-ctrl-saved=r0-r9" } */ ++ ++/* Check that on archs the 'firq' interrupt function type is ++ available, these are the fast interrupts. For fast interrupts, ++ despite the use of 'irq-ctrl-saved', no registers are automatically ++ saved on entry to the function, and so, in the following register ++ r0 to r9 should all be saved to the stack. ++ ++ We also take the opportunity to check the use of the 'rtie' ++ instruction at the end of the interrupt function. */ ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ asm ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9"); ++} ++/* { dg-final { scan-assembler-times "r2,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r4,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler "rtie" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/firq-2.c b/gcc/testsuite/gcc.target/arc/firq-2.c +new file mode 100644 +index 000000000000..dc7dafca11a3 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-2.c +@@ -0,0 +1,31 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O0 -mll64 -mirq-ctrl-saved=r0-r9 -mrgf-banked-regs=4" } */ ++ ++/* Check that on archs the 'firq' interrupt function type is ++ available, these are the fast interrupts. For fast interrupts, ++ despite the use of 'irq-ctrl-saved', no registers are automatically ++ saved on stack on entry to the function. However, the cpu save via ++ bank switch R0-R3. ++ ++ We also take the opportunity to check the use of the 'rtie' instruction ++ at the end of the interrupt function. */ ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ asm ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9"); ++} ++/* { dg-final { scan-assembler-not "r0,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "push.*r0" } } */ ++/* { dg-final { scan-assembler-not "r1,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r2,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r3,\\\[sp" } } */ ++/* { dg-final { scan-assembler "st.*r4,\\\[sp" } } */ ++/* { dg-final { scan-assembler "st.*r6,\\\[sp,\[0-9\]+\\\]" } } */ ++/* { dg-final { scan-assembler "st.*r8,\\\[sp,\[0-9\]+\\\]" } } */ ++/* { dg-final { scan-assembler "rtie" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/firq-3.c b/gcc/testsuite/gcc.target/arc/firq-3.c +new file mode 100644 +index 000000000000..a1d604d8ef75 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-3.c +@@ -0,0 +1,40 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O2 -mll64 -mrgf-banked-regs=8" } */ ++ ++/* Check if R4 to R11 and R16-R27 are correctly saved on stack. */ ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ asm volatile ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9", ++ "r10", "r11", "r12", "r13", "r14", ++ "r15", "r16", "r17", "r18", "r19", ++ "r20", "r21", "r22", "r23", "r24", ++ "r25", "fp"); ++} ++/* { dg-final { scan-assembler-not "r0,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "push.*r0" } } */ ++/* { dg-final { scan-assembler-not "r1,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r2,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r3,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r12,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r13,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r14,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "r15,\\\[sp" } } */ ++ ++/* { dg-final { scan-assembler-times "r4,\\\[sp" 2 } } */ ++/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r10,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r16,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r18,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r20,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r24,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "fp,\\\[sp," 2 } } */ ++ ++/* { dg-final { scan-assembler "rtie" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/firq-4.c b/gcc/testsuite/gcc.target/arc/firq-4.c +new file mode 100644 +index 000000000000..03d3746a500d +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-4.c +@@ -0,0 +1,31 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O2 -mll64 -mrgf-banked-regs=16" } */ ++ ++/* Check if R4-R9 and R16-R25 are correctly saved on stack. */ ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ asm volatile ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9", ++ "r10", "r11", "r12", "r13", "r14", ++ "r15", "r16", "r17", "r18", "r19", ++ "r20", "r21", "r22", "r23", "r24", ++ "r25", "fp"); ++} ++/* { dg-final { scan-assembler-times "r4,\\\[sp" 2 } } */ ++/* { dg-final { scan-assembler-times "r6,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r8,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++ ++/* { dg-final { scan-assembler-times "r16,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r18,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r20,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++/* { dg-final { scan-assembler-times "r24,\\\[sp,\[0-9\]+\\\]" 2 } } */ ++ ++/* { dg-final { scan-assembler-not "fp,\\\[sp" } } */ ++/* { dg-final { scan-assembler-not "push.*fp" } } */ ++/* { dg-final { scan-assembler "mov_s.*fp,sp" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/firq-5.c b/gcc/testsuite/gcc.target/arc/firq-5.c +new file mode 100644 +index 000000000000..29f17a3f0ccc +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-5.c +@@ -0,0 +1,15 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O2 -mrgf-banked-regs=16" } */ ++ ++/* Check if blink is pushed on the stack or not. */ ++ ++extern void bar (void); ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ bar (); ++} ++/* { dg-final { scan-assembler-not "push.*blink" } } */ ++/* { dg-final { scan-assembler-not "pop.*blink" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/firq-6.c b/gcc/testsuite/gcc.target/arc/firq-6.c +new file mode 100644 +index 000000000000..9421200d6304 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/firq-6.c +@@ -0,0 +1,21 @@ ++/* { dg-do compile } */ ++/* { dg-require-effective-target archs }*/ ++/* { dg-options "-O2 -mll64 -mrgf-banked-regs=32" } */ ++ ++/* Check if we have any register saved on stack. */ ++ ++void __attribute__ ((interrupt("firq"))) ++handler1 (void) ++{ ++ asm volatile ("" ++ : ++ : ++ : "r0", "r1", "r2", "r3", "r4", ++ "r5", "r6", "r7", "r8", "r9", ++ "r10", "r11", "r12", "r13", "r14", ++ "r15", "r16", "r17", "r18", "r19", ++ "r20", "r21", "r22", "r23", "r24", ++ "r25", "fp"); ++} ++/* { dg-final { scan-assembler-not "(s|l)(t|d)d.*r\[0-9\]+,\\\[sp,\[0-9\]+\\\]" } } */ ++/* { dg-final { scan-assembler "mov_s.*fp,sp" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0054-ARC-Add-support-for-QuarkSE2-EM-cpu.patch b/toolchain/gcc/patches/6.3.0/0054-ARC-Add-support-for-QuarkSE2-EM-cpu.patch new file mode 100644 index 0000000..fed1163 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0054-ARC-Add-support-for-QuarkSE2-EM-cpu.patch @@ -0,0 +1,269 @@ +From 05584c58a95a9d16a5a92aaab0bd9bbbee36b5c9 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 5 Oct 2016 15:02:32 +0200 +Subject: [PATCH 54/89] [ARC] Add support for QuarkSE2 EM cpu. + +gcc/ +2016-10-05 Claudiu Zissulescu + + * config/arc/arc-arches.def: Recognize Quarkse2 options as valid + ones for ARC EM architecture. + * config/arc/arc-cpus.def (quarkse2_em): New cpu definition. + * config/arc/arc-options.def (FL_FPX_QUARK2): Define. + (FL_QUARK2): Define. + * config/arc/arc-opts.h (FPX_QK2): Define. + (FPU_FPUDA_QK2): Likewise. + * config/arc/arc-tables.opt: Regenerate. + * config/arc/arc.h (TARGET_FPU_QUARK2): Define. + * config/arc/arc.md (divsf3): Allow it for QuarkSE2 cpus as well. + (sqrtsf2): Likewise. + * config/arc/fpx.md (divsf3_quark): Allow it for QuarkSE2 cpus as + well. + (sqrtsf2_quark): Likewise. + * config/arc/genmultilib.awk (ARC_CPU): Create quark2 multilib + option. + * config/arc/t-multilib: Regenerate. + * config/arc/arc-c.def (__ARC_FPU_QUARK2__): Define. + * config/arc/driver-arc.c (arc_cpu_to_as): Consider fpuda for + QuarkSE2 when assembling. + * Doc/invoke.texi (ARC options): Document quarkse2_em mcpu option. +--- + gcc/config/arc/arc-arches.def | 2 +- + gcc/config/arc/arc-c.def | 1 + + gcc/config/arc/arc-cpus.def | 1 + + gcc/config/arc/arc-options.def | 2 ++ + gcc/config/arc/arc-opts.h | 4 ++++ + gcc/config/arc/arc-tables.opt | 3 +++ + gcc/config/arc/arc.h | 5 ++++- + gcc/config/arc/arc.md | 8 ++++---- + gcc/config/arc/driver-arc.c | 2 +- + gcc/config/arc/fpx.md | 4 ++-- + gcc/config/arc/genmultilib.awk | 2 ++ + gcc/config/arc/t-multilib | 5 +++-- + gcc/doc/invoke.texi | 5 +++++ + 13 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/gcc/config/arc/arc-arches.def b/gcc/config/arc/arc-arches.def +index db96ce1241cb..846cb85f91e9 100644 +--- a/gcc/config/arc/arc-arches.def ++++ b/gcc/config/arc/arc-arches.def +@@ -19,7 +19,7 @@ + + ARC_ARCH("arcem", em, FL_MPYOPT_1_6 | FL_DIVREM | FL_CD | FL_NORM \ + | FL_BS | FL_SWAP | FL_FPUS | FL_SPFP | FL_DPFP \ +- | FL_SIMD | FL_FPUDA | FL_QUARK, 0) ++ | FL_SIMD | FL_FPUDA | FL_QUARK | FL_QUARK2, 0) + ARC_ARCH("archs", hs, FL_MPYOPT_7_9 | FL_DIVREM | FL_NORM | FL_CD \ + | FL_ATOMIC | FL_LL64 | FL_BS | FL_SWAP \ + | FL_FPUS | FL_FPUD, \ +diff --git a/gcc/config/arc/arc-c.def b/gcc/config/arc/arc-c.def +index fd643760d88e..6f5da99033f2 100644 +--- a/gcc/config/arc/arc-c.def ++++ b/gcc/config/arc/arc-c.def +@@ -59,6 +59,7 @@ ARC_C_DEF ("__ARC_FPU_SP_FMA__", TARGET_FP_SP_FUSED) + ARC_C_DEF ("__ARC_FPU_DP_FMA__", TARGET_FP_DP_FUSED) + ARC_C_DEF ("__ARC_FPU_ASSIST__", TARGET_FP_DP_AX) + ARC_C_DEF ("__ARC_FPX_QUARK__", TARGET_FPX_QUARK) ++ARC_C_DEF ("__ARC_FPU_QUARK2__", TARGET_FPU_QUARK2) + + /* To be deprecated. */ + ARC_C_DEF ("__A6__", TARGET_ARC600) +diff --git a/gcc/config/arc/arc-cpus.def b/gcc/config/arc/arc-cpus.def +index 8782bd5e9263..fe1390360f24 100644 +--- a/gcc/config/arc/arc-cpus.def ++++ b/gcc/config/arc/arc-cpus.def +@@ -24,6 +24,7 @@ ARC_CPU (em4_dmips, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS, NONE) + ARC_CPU (em4_fpus, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUS, NONE) + ARC_CPU (em4_fpuda, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPU_FPUDA, NONE) + ARC_CPU (quarkse_em, em, FL_MPYOPT_3|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPX_QUARK|FL_SPFP|FL_DPFP, NONE) ++ARC_CPU (quarkse2_em, em, FL_MPYOPT_2|FL_CD|FL_DIVREM|FL_NORM|FL_SWAP|FL_BS|FL_FPX_QUARK2, NONE) + + ARC_CPU (hs, hs, 0, NONE) + ARC_CPU (archs, hs, FL_MPYOPT_2|FL_DIVREM|FL_LL64, NONE) +diff --git a/gcc/config/arc/arc-options.def b/gcc/config/arc/arc-options.def +index 778f69d95afe..1a6a9364b0dc 100644 +--- a/gcc/config/arc/arc-options.def ++++ b/gcc/config/arc/arc-options.def +@@ -60,11 +60,13 @@ ARC_OPTX (FL_FPU_FPUD_DIV, (1ULL << 35), arc_fpu_build, FPU_FPUD_DIV, "mfpu=fpu + ARC_OPTX (FL_FPU_FPUD_FMA, (1ULL << 36), arc_fpu_build, FPU_FPUD_FMA, "mfpu=fpud_fma") + ARC_OPTX (FL_FPU_FPUD_ALL, (1ULL << 37), arc_fpu_build, FPU_FPUD_ALL, "mfpu=fpud_all") + ARC_OPTX (FL_FPX_QUARK, (1ULL << 38), arc_fpu_build, FPX_QK, "quarkse fp") ++ARC_OPTX (FL_FPX_QUARK2, (1ULL << 39), arc_fpu_build, FPU_FPUDA_QK2, "quarkse2 fp") + + ARC_OPT (FL_FPUS, (0xFULL << 26), 0, "single precission floating point") + ARC_OPT (FL_FPUDA, (0xFFULL << 26), 0, "double precission fp assist") + ARC_OPT (FL_FPUD, (0xF0FULL << 26), 0, "double precission floating point") + ARC_OPT (FL_QUARK, (1ULL << 38), 0, "Quark SE fp extension") ++ARC_OPT (FL_QUARK2, (1ULL << 39), 0, "Quark SE2 fp extension") + + /* Local Variables: */ + /* mode: c */ +diff --git a/gcc/config/arc/arc-opts.h b/gcc/config/arc/arc-opts.h +index 819b97c299f6..0cd2ebe8f22c 100644 +--- a/gcc/config/arc/arc-opts.h ++++ b/gcc/config/arc/arc-opts.h +@@ -50,6 +50,8 @@ enum processor_type + #define FPX_DP 0x0100 + /* Quark SE floating point instructions. */ + #define FPX_QK 0x0200 ++/* Quark SE2 floating point instructions. */ ++#define FPX_QK2 0x0400 + + /* fpus option combi. */ + #define FPU_FPUS (FPU_SP | FPU_SC) +@@ -75,6 +77,8 @@ enum processor_type + #define FPU_FPUD_FMA (FPU_FPUS_FMA | FPU_DP | FPU_DC | FPU_DF) + /* fpud_all option combi. */ + #define FPU_FPUD_ALL (FPU_FPUS_ALL | FPU_DP | FPU_DC | FPU_DF | FPU_DD) ++/* QuarkSE2 combi. */ ++#define FPU_FPUDA_QK2 (FPU_SP | FPU_SC | FPX_DP | FPX_QK2) + + /* Default FPU option value. */ + #define DEFAULT_arc_fpu_build 0x10000000 +diff --git a/gcc/config/arc/arc-tables.opt b/gcc/config/arc/arc-tables.opt +index 41e325c91d57..20dad4a148e6 100644 +--- a/gcc/config/arc/arc-tables.opt ++++ b/gcc/config/arc/arc-tables.opt +@@ -46,6 +46,9 @@ EnumValue + Enum(processor_type) String(quarkse_em) Value(PROCESSOR_quarkse_em) + + EnumValue ++Enum(processor_type) String(quarkse2_em) Value(PROCESSOR_quarkse2_em) ++ ++EnumValue + Enum(processor_type) String(hs) Value(PROCESSOR_hs) + + EnumValue +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 86bc6088fbcd..cf13a7fa9fc3 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1631,5 +1631,8 @@ enum + /* Custom FP instructions used by QuarkSE EM cpu. */ + #define TARGET_FPX_QUARK (TARGET_EM && TARGET_SPFP \ + && (arc_fpu_build == FPX_QK)) +- ++/* Custom FP instructions used by QuarkSE2 EM cpu. */ ++#define TARGET_FPU_QUARK2 (TARGET_EM \ ++ && ((arc_fpu_build \ ++ & FPU_FPUDA_QK2) == FPU_FPUDA_QK2)) + #endif /* GCC_ARC_H */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 4306d7229437..8c492750fd13 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -5922,9 +5922,9 @@ + [(set (match_operand:SF 0 "register_operand" "") + (div:SF (match_operand:SF 1 "nonmemory_operand" "") + (match_operand:SF 2 "nonmemory_operand" "")))] +- "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" ++ "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT || TARGET_FPU_QUARK2" + " +- if (TARGET_FPX_QUARK) ++ if (TARGET_FPX_QUARK || TARGET_FPU_QUARK2) + { + operands[1] = force_reg (SFmode, operands[1]); + operands[2] = force_reg (SFmode, operands[2]); +@@ -5941,9 +5941,9 @@ + (define_expand "sqrtsf2" + [(set (match_operand:SF 0 "register_operand" "") + (sqrt:SF (match_operand:SF 1 "nonmemory_operand" "")))] +- "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT" ++ "TARGET_FPX_QUARK || TARGET_FP_SP_SQRT || TARGET_FPU_QUARK2" + " +- if (TARGET_FPX_QUARK) ++ if (TARGET_FPX_QUARK || TARGET_FPU_QUARK2) + { + operands[1] = force_reg (SFmode, operands[1]); + } +diff --git a/gcc/config/arc/driver-arc.c b/gcc/config/arc/driver-arc.c +index c51b70803413..7519ce50c070 100644 +--- a/gcc/config/arc/driver-arc.c ++++ b/gcc/config/arc/driver-arc.c +@@ -56,7 +56,7 @@ arc_cpu_to_as (int argc, const char **argv) + name = "-mcode-density"; + else + name = ""; +- if (arc_selected_cpu->flags & FL_FPUDA) ++ if (arc_selected_cpu->flags & (FL_FPUDA | FL_QUARK2)) + name = concat ("-mfpuda ", name, NULL); + if (arc_selected_cpu->flags & FL_SPFP) + name = concat ("-mspfp ", name, NULL); +diff --git a/gcc/config/arc/fpx.md b/gcc/config/arc/fpx.md +index 094319e1ce4f..a0ae3b4ed9b2 100644 +--- a/gcc/config/arc/fpx.md ++++ b/gcc/config/arc/fpx.md +@@ -678,7 +678,7 @@ + [(set (match_operand:SF 0 "register_operand" "=r") + (div:SF (match_operand:SF 1 "register_operand" "r") + (match_operand:SF 2 "register_operand" "r")))] +- "TARGET_FPX_QUARK" ++ "TARGET_FPX_QUARK || TARGET_FPU_QUARK2" + "dsp_fp_div\\t%0,%1,%2" + [(set_attr "length" "4") + (set_attr "predicable" "no") +@@ -687,7 +687,7 @@ + (define_insn "*sqrtsf2_quark" + [(set (match_operand:SF 0 "register_operand" "=r") + (sqrt:SF (match_operand:SF 1 "register_operand" "r")))] +- "TARGET_FPX_QUARK" ++ "TARGET_FPX_QUARK || TARGET_FPU_QUARK2" + "dsp_fp_sqrt\\t%0,%1" + [(set_attr "length" "4") + (set_attr "predicable" "no") +diff --git a/gcc/config/arc/genmultilib.awk b/gcc/config/arc/genmultilib.awk +index 61bda419c8a8..a8a50a8d17e2 100644 +--- a/gcc/config/arc/genmultilib.awk ++++ b/gcc/config/arc/genmultilib.awk +@@ -126,6 +126,8 @@ BEGIN { + line = line "/mmul32x16" + else if (cpu_flg[i] == "FL_FPX_QUARK") + line = line "/quark" ++ else if (cpu_flg[i] == "FL_FPX_QUARK2") ++ line = line "/quark2" + else if (cpu_flg[i] == "FL_SPFP") + line = line "/spfp" + else if (cpu_flg[i] == "FL_DPFP") +diff --git a/gcc/config/arc/t-multilib b/gcc/config/arc/t-multilib +index 0f1c398d61f8..7e21f947621f 100644 +--- a/gcc/config/arc/t-multilib ++++ b/gcc/config/arc/t-multilib +@@ -21,9 +21,9 @@ + # along with GCC; see the file COPYING3. If not see + # . + +-MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400 ++MULTILIB_OPTIONS = mcpu=em/mcpu=arcem/mcpu=em4/mcpu=em4_dmips/mcpu=em4_fpus/mcpu=em4_fpuda/mcpu=quarkse_em/mcpu=quarkse2_em/mcpu=hs/mcpu=archs/mcpu=hs34/mcpu=hs38/mcpu=hs38_linux/mcpu=arc600/mcpu=arc600_norm/mcpu=arc600_mul64/mcpu=arc600_mul32x16/mcpu=arc601/mcpu=arc601_norm/mcpu=arc601_mul64/mcpu=arc601_mul32x16/mcpu=arc700/mcpu=nps400 + +-MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400 ++MULTILIB_DIRNAMES = em arcem em4 em4_dmips em4_fpus em4_fpuda quarkse_em quarkse2_em hs archs hs34 hs38 hs38_linux arc600 arc600_norm arc600_mul64 arc600_mul32x16 arc601 arc601_norm arc601_mul64 arc601_mul32x16 arc700 nps400 + + MULTILIB_REUSE =mcpu.arcem=mcpu.em/mmpy-option.2/mcode-density/mbarrel-shifter + MULTILIB_REUSE +=mcpu.em4=mcpu.em/mcode-density +@@ -31,6 +31,7 @@ MULTILIB_REUSE +=mcpu.em4_dmips=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mno + MULTILIB_REUSE +=mcpu.em4_fpus=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpus + MULTILIB_REUSE +=mcpu.em4_fpuda=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/mfpu.fpuda + MULTILIB_REUSE +=mcpu.quarkse_em=mcpu.em/mmpy-option.3/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/quark/spfp/dpfp ++MULTILIB_REUSE +=mcpu.quarkse2_em=mcpu.em/mmpy-option.2/mcode-density/mdiv-rem/mnorm/mnorm/mbarrel-shifter/quark2 + MULTILIB_REUSE +=mcpu.archs=mcpu.hs/mmpy-option.2/mdiv-rem/mll64 + MULTILIB_REUSE +=mcpu.hs34=mcpu.hs/mmpy-option.2 + MULTILIB_REUSE +=mcpu.hs38=mcpu.hs/mmpy-option.9/mdiv-rem/mll64 +diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi +index 79ee47c2820f..c81f1e98a809 100644 +--- a/gcc/doc/invoke.texi ++++ b/gcc/doc/invoke.texi +@@ -13272,6 +13272,11 @@ extension. + Compile for ARC EM4 DMIPS cpu with single precision floating point and + double assists instructions. + ++@item quarkse2_em ++@opindex quarkse2_em ++Compile for ARC EM CPU on Intel QuarkSE2 microcontroller with single ++precision floating point. ++ + @item hs + @opindex hs + Compile for ARC HS cpu with no hardware extension, except the atomic +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0055-ARC-Fix-move_double_src_operand-predicate.patch b/toolchain/gcc/patches/6.3.0/0055-ARC-Fix-move_double_src_operand-predicate.patch new file mode 100644 index 0000000..9f076ac --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0055-ARC-Fix-move_double_src_operand-predicate.patch @@ -0,0 +1,37 @@ +From 0a2de97b8dc588e4b43808004370e5123e5122e2 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 7 Oct 2016 16:20:16 +0200 +Subject: [PATCH 55/89] [ARC] Fix move_double_src_operand predicate. + +Durring compilation process, (subreg (mem ...) ...) can occur. Hence, +we need to check if the address of mem is a valid one. This patch is +fixing this check by directly calling the address_operand, instead of +calling move_double_src_operand, as the latter is always checking +against the original mode, thus, returning false when the inner and +outer modes are different. + +gcc/ +2016-10-07 Claudiu Zissulescu + + * config/arc/predicates.md (move_double_src_operand): Replace the + call to move_double_src_operand with a call to address_operand. +--- + gcc/config/arc/predicates.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 7824f7234d7d..5c95c207758d 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -317,7 +317,7 @@ + /* (subreg (mem ...) ...) can occur here if the inner part was once a + pseudo-reg and is now a stack slot. */ + if (GET_CODE (SUBREG_REG (op)) == MEM) +- return move_double_src_operand (SUBREG_REG (op), mode); ++ return address_operand (XEXP (SUBREG_REG (op), 0), mode); + else + return register_operand (op, mode); + case MEM : +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0056-ARC-Remove-old-prof-patterns.patch b/toolchain/gcc/patches/6.3.0/0056-ARC-Remove-old-prof-patterns.patch new file mode 100644 index 0000000..807d93d --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0056-ARC-Remove-old-prof-patterns.patch @@ -0,0 +1,107 @@ +From 853d24cf2a826ca6e1922eec3f72ee83fdc892c7 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 10 Oct 2016 13:02:28 +0200 +Subject: [PATCH 56/89] [ARC] Remove old prof patterns. + +gcc/ +2016-10-10 Claudiu Zissulescu + + * config/arc/arc.md (call_prof): Remove. + (call_value_prof): Likewise. + (sibcall_prof): Likewise. + (sibcall_value_prof): Likewise. +--- + gcc/config/arc/arc.md | 63 --------------------------------------------------- + 1 file changed, 63 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 8c492750fd13..a193745dc9ba 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -4111,20 +4111,6 @@ + (set_attr "predicable" "no,no,yes,yes,no,yes,no,yes") + (set_attr "length" "*,*,4,4,4,4,4,8")]) + +-(define_insn "call_prof" +- [(call (mem:SI (match_operand:SI 0 "symbolic_operand" "Cbr,Cal")) +- (match_operand 1 "" "")) +- (clobber (reg:SI 31)) +- (use (reg:SI 8)) +- (use (reg:SI 9))] +- "" +- "@ +- bl%!%* %P0;2 +- jl%! %^%S0" +- [(set_attr "type" "call,call_no_delay_slot") +- (set_attr "predicable" "yes,yes") +- (set_attr "length" "4,8")]) +- + (define_expand "call_value" + ;; operand 2 is stack_size_rtx + ;; operand 3 is next_arg_register +@@ -4174,22 +4160,6 @@ + ; use it for lack of inter-procedural branch shortening. + ; Link-time relaxation would help... + +- +-(define_insn "call_value_prof" +- [(set (match_operand 0 "dest_reg_operand" "=r,r") +- (call (mem:SI (match_operand:SI 1 "symbolic_operand" "Cbr,Cal")) +- (match_operand 2 "" ""))) +- (clobber (reg:SI 31)) +- (use (reg:SI 8)) +- (use (reg:SI 9))] +- "" +- "@ +- bl%!%* %P1;1 +- jl%! %^%S1" +- [(set_attr "type" "call,call_no_delay_slot") +- (set_attr "predicable" "yes,yes") +- (set_attr "length" "4,8")]) +- + (define_insn "nop" + [(const_int 0)] + "" +@@ -4684,39 +4654,6 @@ + (set_attr "is_SIBCALL" "yes")] + ) + +-(define_insn "sibcall_prof" +- [(call (mem:SI (match_operand:SI 0 "call_address_operand" "Cbr,Cal")) +- (match_operand 1 "" "")) +- (simple_return) +- (use (match_operand 2 "" "")) +- (use (reg:SI 8)) +- (use (reg:SI 9))] +- "" +- "@ +- b%!%* %P0;2 +- j%! %^%S0;2" +- [(set_attr "type" "call,call_no_delay_slot") +- (set_attr "predicable" "yes") +- (set_attr "is_SIBCALL" "yes")] +-) +- +-(define_insn "sibcall_value_prof" +- [(set (match_operand 0 "dest_reg_operand" "") +- (call (mem:SI (match_operand:SI 1 "call_address_operand" "Cbr,Cal")) +- (match_operand 2 "" ""))) +- (simple_return) +- (use (match_operand 3 "" "")) +- (use (reg:SI 8)) +- (use (reg:SI 9))] +- "" +- "@ +- b%!%* %P1;1 +- j%! %^%S1;1" +- [(set_attr "type" "call,call_no_delay_slot") +- (set_attr "predicable" "yes") +- (set_attr "is_SIBCALL" "yes")] +-) +- + (define_expand "prologue" + [(pc)] + "" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0057-ARC-Update-mode_dependent_address_p-hook.patch b/toolchain/gcc/patches/6.3.0/0057-ARC-Update-mode_dependent_address_p-hook.patch new file mode 100644 index 0000000..fd62360 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0057-ARC-Update-mode_dependent_address_p-hook.patch @@ -0,0 +1,40 @@ +From 0886f8cda0d8969ad02611a154f602de2f8b0fb7 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 11 Oct 2016 18:58:56 +0200 +Subject: [PATCH 57/89] [ARC] Update mode_dependent_address_p hook. + +Update arc_mode_dependent_address_p to avoid emitting subreg(mem (reg +..)) when expanding by relaxing the conditions. + +gcc/ +2016-10-11 Claudiu Zissulescu + + * config/arc/arc.c (arc_mode_dependent_address_p): Relax + conditions to take advantage of various optimizations. +--- + gcc/config/arc/arc.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 282e7d45aa4b..7033ce960aa7 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -5964,13 +5964,9 @@ arc_mode_dependent_address_p (const_rtx addr, addr_space_t) + { + /* SYMBOL_REF is not mode dependent: it is either a small data reference, + which is valid for loads and stores, or a limm offset, which is valid for +- loads. */ +- /* Scaled indices are scaled by the access mode; likewise for scaled +- offsets, which are needed for maximum offset stores. */ ++ loads. Scaled indices are scaled by the access mode. */ + if (GET_CODE (addr) == PLUS +- && (GET_CODE (XEXP ((addr), 0)) == MULT +- || (CONST_INT_P (XEXP ((addr), 1)) +- && !SMALL_INT (INTVAL (XEXP ((addr), 1)))))) ++ && GET_CODE (XEXP ((addr), 0)) == MULT) + return true; + return false; + } +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0058-Changed-tests-to-verify-shared-option.patch b/toolchain/gcc/patches/6.3.0/0058-Changed-tests-to-verify-shared-option.patch new file mode 100644 index 0000000..b87f0ed --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0058-Changed-tests-to-verify-shared-option.patch @@ -0,0 +1,56 @@ +From c78838d08006be4fd90fe9d598f3052c27120d93 Mon Sep 17 00:00:00 2001 +From: Cupertino Miranda +Date: Thu, 13 Oct 2016 16:37:18 +0200 +Subject: [PATCH 58/89] Changed tests to verify -shared option. + +Verify for option -shared instead of just the availability of -fpic. + +gcc/testsuite/ +2016-10-13 Cupertino Miranda + + gcc.dg/lto/pr54709_0.c: Added + { dg-require-effective-target shared } to test. + gcc.dg/lto/pr61526_0.c: Likewise. + gcc.dg/lto/pr64415_0.c: Likewise. +--- + gcc/testsuite/gcc.dg/lto/pr54709_0.c | 1 + + gcc/testsuite/gcc.dg/lto/pr61526_0.c | 1 + + gcc/testsuite/gcc.dg/lto/pr64415_0.c | 1 + + 3 files changed, 3 insertions(+) + +diff --git a/gcc/testsuite/gcc.dg/lto/pr54709_0.c b/gcc/testsuite/gcc.dg/lto/pr54709_0.c +index f3db5dcbbc48..69697d89158a 100644 +--- a/gcc/testsuite/gcc.dg/lto/pr54709_0.c ++++ b/gcc/testsuite/gcc.dg/lto/pr54709_0.c +@@ -1,6 +1,7 @@ + /* { dg-lto-do link } */ + /* { dg-require-visibility "hidden" } */ + /* { dg-require-effective-target fpic } */ ++/* { dg-require-effective-target shared } */ + /* { dg-extra-ld-options { -shared } } */ + /* { dg-lto-options { { -fPIC -fvisibility=hidden -flto } } } */ + +diff --git a/gcc/testsuite/gcc.dg/lto/pr61526_0.c b/gcc/testsuite/gcc.dg/lto/pr61526_0.c +index 8a631f058ed5..d3e2c8008dbe 100644 +--- a/gcc/testsuite/gcc.dg/lto/pr61526_0.c ++++ b/gcc/testsuite/gcc.dg/lto/pr61526_0.c +@@ -1,4 +1,5 @@ + /* { dg-require-effective-target fpic } */ ++/* { dg-require-effective-target shared } */ + /* { dg-lto-do link } */ + /* { dg-lto-options { { -fPIC -flto -flto-partition=1to1 } } } */ + /* { dg-extra-ld-options { -shared } } */ +diff --git a/gcc/testsuite/gcc.dg/lto/pr64415_0.c b/gcc/testsuite/gcc.dg/lto/pr64415_0.c +index 4faab2bac354..11218e072859 100644 +--- a/gcc/testsuite/gcc.dg/lto/pr64415_0.c ++++ b/gcc/testsuite/gcc.dg/lto/pr64415_0.c +@@ -1,5 +1,6 @@ + /* { dg-lto-do link } */ + /* { dg-require-effective-target fpic } */ ++/* { dg-require-effective-target shared } */ + /* { dg-lto-options { { -O -flto -fpic } } } */ + /* { dg-extra-ld-options { -shared } } */ + /* { dg-extra-ld-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0059-ARC-DWARF-emitting-cleanup.patch b/toolchain/gcc/patches/6.3.0/0059-ARC-DWARF-emitting-cleanup.patch new file mode 100644 index 0000000..597e767 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0059-ARC-DWARF-emitting-cleanup.patch @@ -0,0 +1,75 @@ +From ccddb9c4a1b84975311dbec4a0354ec5f7c261cc Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 17 Oct 2016 13:10:54 +0200 +Subject: [PATCH 59/89] [ARC] DWARF emitting cleanup. + +The use of CFA_FRAME_BASE_OFFSET and ARG_POINTER_CFA_OFFSET macros +leads to wrong offset calculation for DW_OP_fbreg constructions. +Remove them. + +gcc/ +2016-10-17 Claudiu Zissulescu + + * config/arc/arc-protos.h (arc_decl_pretend_args): Remove. + * config/arc/arc.c (arc_decl_pretend_args): Likewise. + * config/arc/arc.h (CFA_FRAME_BASE_OFFSET): Likewise. + (ARG_POINTER_CFA_OFFSET): Likewise. +--- + gcc/config/arc/arc-protos.h | 1 - + gcc/config/arc/arc.c | 11 ----------- + gcc/config/arc/arc.h | 5 ----- + 3 files changed, 17 deletions(-) + +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 2c11f3557bf2..7b8ceeaa13c1 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -109,7 +109,6 @@ extern int arc_label_align (rtx label); + extern bool arc_need_delay (rtx_insn *insn); + extern bool arc_text_label (rtx_insn *insn); + +-extern int arc_decl_pretend_args (tree decl); + extern bool arc_short_comparison_p (rtx, int); + extern bool arc_epilogue_uses (int regno); + extern bool arc_eh_uses (int regno); +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 7033ce960aa7..6500e3e21f05 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -9717,17 +9717,6 @@ arc_text_label (rtx_insn *label) + return false; + } + +-/* Return the size of the pretend args for DECL. */ +- +-int +-arc_decl_pretend_args (tree decl) +-{ +- /* struct function is in DECL_STRUCT_FUNCTION (decl), but no +- pretend_args there... See PR38391. */ +- gcc_assert (decl == current_function_decl); +- return crtl->args.pretend_args_size; +-} +- + /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble + when compiling with -O2 -freorder-blocks-and-partition -fprofile-use + -D_PROFILE_USE; delay branch scheduling then follows a crossing jump +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index cf13a7fa9fc3..3680261e75e0 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1560,11 +1560,6 @@ extern enum arc_function_type arc_compute_function_type (struct function *); + + #define INIT_EXPANDERS arc_init_expanders () + +-#define CFA_FRAME_BASE_OFFSET(FUNDECL) (-arc_decl_pretend_args ((FUNDECL))) +- +-#define ARG_POINTER_CFA_OFFSET(FNDECL) \ +- (FIRST_PARM_OFFSET (FNDECL) + arc_decl_pretend_args ((FNDECL))) +- + enum + { + ARC_LRA_PRIORITY_NONE, ARC_LRA_PRIORITY_NONCOMPACT, ARC_LRA_PRIORITY_COMPACT +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0060-ARC-Use-long-jumps-for-CRT-calls.patch b/toolchain/gcc/patches/6.3.0/0060-ARC-Use-long-jumps-for-CRT-calls.patch new file mode 100644 index 0000000..3b1e69e --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0060-ARC-Use-long-jumps-for-CRT-calls.patch @@ -0,0 +1,36 @@ +From fc5f2fcf3040f940c63c4f3c6f958b1450ee0f63 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 21 Apr 2016 12:12:30 +0200 +Subject: [PATCH 60/89] [ARC] Use long jumps for CRT calls + +gcc/ +2016-04-21 Claudiu Zissulescu + + * config/arc/arc.h (CRT_CALL_STATIC_FUNCTION): Use long calls. +--- + gcc/config/arc/arc.h | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 3680261e75e0..99c3e6b9b44f 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1494,10 +1494,11 @@ extern enum arc_function_type arc_compute_function_type (struct function *); + /* Called by crtstuff.c to make calls to function FUNCTION that are defined in + SECTION_OP, and then to switch back to text section. */ + #undef CRT_CALL_STATIC_FUNCTION +-#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ +- asm (SECTION_OP "\n\t" \ +- "bl @" USER_LABEL_PREFIX #FUNC "\n" \ +- TEXT_SECTION_ASM_OP); ++#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \ ++ asm (SECTION_OP "\n\t" \ ++ "add r12,pcl,@" USER_LABEL_PREFIX #FUNC "@pcl\n\t" \ ++ "jl [r12]\n" \ ++ TEXT_SECTION_ASM_OP); + + /* This macro expands to the name of the scratch register r12, used for + temporary calculations according to the ABI. */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0061-ARC-Fix-typo-in-arc.opt.patch b/toolchain/gcc/patches/6.3.0/0061-ARC-Fix-typo-in-arc.opt.patch new file mode 100644 index 0000000..7440d17 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0061-ARC-Fix-typo-in-arc.opt.patch @@ -0,0 +1,35 @@ +From 38a5be64dabdf59df0c899b2224de768042a7040 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 2 Nov 2016 11:12:06 +0100 +Subject: [PATCH 61/89] [ARC] Fix typo in arc.opt + +gcc/ +2016-11-02 Claudiu Zissulescu + + * config/arc/arc.opt (marclinux): Fix typo. + (marclinux_prof): Likewise. +--- + gcc/config/arc/arc.opt | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/arc/arc.opt b/gcc/config/arc/arc.opt +index 90ff4ad27f67..c8fb7892bacd 100644 +--- a/gcc/config/arc/arc.opt ++++ b/gcc/config/arc/arc.opt +@@ -319,11 +319,11 @@ Target + Pass -EL option through to linker. + + marclinux +-target ++Target + Pass -marclinux option through to linker. + + marclinux_prof +-target ++Target + Pass -marclinux_prof option through to linker. + + ;; lra is still unproven for ARC, so allow to fall back to reload with -mno-lra. +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0062-ARC-define-SIZE_TYPE-and-PTRDIFF_TYPE-correctly.patch b/toolchain/gcc/patches/6.3.0/0062-ARC-define-SIZE_TYPE-and-PTRDIFF_TYPE-correctly.patch new file mode 100644 index 0000000..018f843 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0062-ARC-define-SIZE_TYPE-and-PTRDIFF_TYPE-correctly.patch @@ -0,0 +1,38 @@ +From bbabc467b57928ec8e1a6fabc4fd1f79421b20a1 Mon Sep 17 00:00:00 2001 +From: Vineet Gupta +Date: Wed, 2 Nov 2016 13:15:51 +0100 +Subject: [PATCH 62/89] [ARC] define SIZE_TYPE and PTRDIFF_TYPE correctly. + +This silences tons of -Wformat= warnings when building ARC Linux kernel +with gcc 6.x (and restores the ARC gcc 4.8.x behaviour) which had +similar fix. + +gcc/ +2016-11-02 Vineet Gupta + + * config/arc/arc.h (SIZE_TYPE): Define as unsigned int. + (PTRDIFF_TYPE): Define as int. +--- + gcc/config/arc/arc.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 99c3e6b9b44f..e071946d8be5 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -282,10 +282,10 @@ if (GET_MODE_CLASS (MODE) == MODE_INT \ + #define DEFAULT_SIGNED_CHAR 0 + + #undef SIZE_TYPE +-#define SIZE_TYPE "long unsigned int" ++#define SIZE_TYPE "unsigned int" + + #undef PTRDIFF_TYPE +-#define PTRDIFF_TYPE "long int" ++#define PTRDIFF_TYPE "int" + + #undef WCHAR_TYPE + #define WCHAR_TYPE "int" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0063-ARC-HACK-Hard-check-for-the-LP-size-constraints.patch b/toolchain/gcc/patches/6.3.0/0063-ARC-HACK-Hard-check-for-the-LP-size-constraints.patch new file mode 100644 index 0000000..7a54ac4 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0063-ARC-HACK-Hard-check-for-the-LP-size-constraints.patch @@ -0,0 +1,38 @@ +From 634a22b3eef86b498ef4f011ceb7e64713090dfc Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 2 Nov 2016 17:05:21 +0100 +Subject: [PATCH 63/89] [ARC] [HACK] Hard check for the LP size constraints. + +LP instruction can accept an s13 displacement. However, the procedure +which checks if the loop body fits is not complete. For example, when +the end of the loop is before the loop begin, then the size +computation is totaly wrong. As a solution, I check if the size +computation has been done until we found a loop end to validate it, +otherwise we will fall back on SR implementation. + +gcc/ +2016-11-02 Claudiu Zissulescu + + * config/arc/arc.md (doloop_begin_i): Check if size is computed + correctly. +--- + gcc/config/arc/arc.md | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index a193745dc9ba..211a98dac72c 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -5005,6 +5005,9 @@ + len = get_attr_length (scan); + size += len; + } ++ /* Check if we found the end of the loop. If not go safe. */ ++ if (!scan) ++ size = 2048; + /* Try to verify that there are at least three instruction fetches + between the loop setup and the first encounter of the loop end. */ + for (scan = NEXT_INSN (insn); scan && n_insns < 3; scan = NEXT_INSN (scan)) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0064-ARC-Fix-sub_n-pattern.patch b/toolchain/gcc/patches/6.3.0/0064-ARC-Fix-sub_n-pattern.patch new file mode 100644 index 0000000..9988200 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0064-ARC-Fix-sub_n-pattern.patch @@ -0,0 +1,29 @@ +From a75f253251b43b5a5927d8d72c547b2e2e694276 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 4 Nov 2016 11:46:59 +0100 +Subject: [PATCH 64/89] [ARC] Fix sub_n pattern. + +gcc/ +2016-11-04 Claudiu Zissulescu + + * config/arc/arc.md (sub_n): Use 'c' constraint letter. +--- + gcc/config/arc/arc.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 211a98dac72c..46eb6aff9aee 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -2944,7 +2944,7 @@ + (define_insn "*sub_n" + [(set (match_operand:SI 0 "dest_reg_operand" "=Rcw,w,w") + (minus:SI (match_operand:SI 1 "nonmemory_operand" "0,c,?Cal") +- (mult:SI (match_operand:SI 2 "register_operand" "w,w,w") ++ (mult:SI (match_operand:SI 2 "register_operand" "c,c,c") + (match_operand:SI 3 "_2_4_8_operand" ""))))] + "" + "sub%z3%? %0,%1,%2" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0065-ARC-Make-mulsi-for-A700-pattern-commutative.patch b/toolchain/gcc/patches/6.3.0/0065-ARC-Make-mulsi-for-A700-pattern-commutative.patch new file mode 100644 index 0000000..ebf6c45 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0065-ARC-Make-mulsi-for-A700-pattern-commutative.patch @@ -0,0 +1,29 @@ +From 55c15dbadc2fe6f8c96b7965daf78a2c8a76325e Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 10 Nov 2016 11:09:22 +0100 +Subject: [PATCH 65/89] [ARC] Make mulsi for A700 pattern commutative. + +gcc/ +2016-11-10 Claudiu Zissulescu + + * config/arc/arc.md (mulsi3_700): Make it commutative. +--- + gcc/config/arc/arc.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 46eb6aff9aee..59805f11076f 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -2084,7 +2084,7 @@ + ; like MPY or MPYU. + (define_insn "mulsi3_700" + [(set (match_operand:SI 0 "mpy_dest_reg_operand" "=Rcr,r,r,Rcr,r") +- (mult:SI (match_operand:SI 1 "register_operand" " 0,c,0,0,c") ++ (mult:SI (match_operand:SI 1 "register_operand" "%0,c,0,0,c") + (match_operand:SI 2 "nonmemory_operand" "cL,cL,I,Cal,Cal")))] + "TARGET_ARC700_MPY" + "mpyu%? %0,%1,%2" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0066-ARC-Fix-LE-tests-for-nps400-variant.patch b/toolchain/gcc/patches/6.3.0/0066-ARC-Fix-LE-tests-for-nps400-variant.patch new file mode 100644 index 0000000..a7c4190 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0066-ARC-Fix-LE-tests-for-nps400-variant.patch @@ -0,0 +1,125 @@ +From 42125f5d57fe0b8a2a4f7ee8e78eaf28ec716542 Mon Sep 17 00:00:00 2001 +From: Andrew Burgess +Date: Wed, 16 Nov 2016 12:55:43 +0100 +Subject: [PATCH 66/89] [ARC] Fix LE tests for nps400 variant. + +gcc/arc: New peephole2 and little endian arc test fixes + +Resolve some test failures introduced for little endian arc as a result +of the recent arc/nps400 additions. + +There's a new peephole2 optimisation to merge together two zero_extracts +in order that the movb instruction can be used. + +One of the test cases is extended so that the test does something +meaningful in both big and little endian arc mode. + +Other tests have their expected results updated to reflect improvements +in other areas of GCC. + +gcc/ChangeLog: + + Andrew Burgess + + * config/arc/arc.md (movb peephole2): New peephole2 to merge two + zero_extract operations to allow a movb to occur. + * gcc.target/arc/movb-1.c: Update little endian arc results. + * gcc.target/arc/movb-2.c: Likewise. + * gcc.target/arc/movb-5.c: Likewise. + * gcc.target/arc/movh_cl-1.c: Extend test to cover little endian + arc. +--- + gcc/config/arc/arc.md | 14 ++++++++++++++ + gcc/testsuite/gcc.target/arc/movb-1.c | 2 +- + gcc/testsuite/gcc.target/arc/movb-2.c | 2 +- + gcc/testsuite/gcc.target/arc/movb-5.c | 2 +- + gcc/testsuite/gcc.target/arc/movh_cl-1.c | 11 +++++++++++ + 5 files changed, 28 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 59805f11076f..992a114f3a38 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -6141,6 +6141,20 @@ + "" + [(set_attr "length" "0")]) + ++(define_peephole2 ++ [(set (match_operand:SI 0 "register_operand" "") ++ (zero_extract:SI (match_dup 0) ++ (match_operand:SI 1 "const_int_operand" "") ++ (match_operand:SI 2 "const_int_operand" ""))) ++ (set (zero_extract:SI (match_operand:SI 3 "register_operand" "") ++ (match_dup 1) ++ (match_dup 2)) ++ (match_dup 0))] ++ "TARGET_NPS_BITOPS ++ && !reg_overlap_mentioned_p (operands[0], operands[3])" ++ [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2)) ++ (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))]) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +diff --git a/gcc/testsuite/gcc.target/arc/movb-1.c b/gcc/testsuite/gcc.target/arc/movb-1.c +index 965fd66aa99c..37f3fd8b27c4 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-1.c ++++ b/gcc/testsuite/gcc.target/arc/movb-1.c +@@ -11,4 +11,4 @@ f (void) + bar.b = foo.b; + } + /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *5, *3, *8" { target arceb-*-* } } } */ +-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *19, *21, *8" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *3, *5, *8" { target arc-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-2.c b/gcc/testsuite/gcc.target/arc/movb-2.c +index 9bd6d4187fd3..1ac18d05e4c0 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-2.c ++++ b/gcc/testsuite/gcc.target/arc/movb-2.c +@@ -10,5 +10,5 @@ f (void) + { + bar.b = foo.b; + } +-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *23, *9" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */ + /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movb-5.c b/gcc/testsuite/gcc.target/arc/movb-5.c +index 0bcdd1c7874c..c8159feb6032 100644 +--- a/gcc/testsuite/gcc.target/arc/movb-5.c ++++ b/gcc/testsuite/gcc.target/arc/movb-5.c +@@ -10,5 +10,5 @@ f (void) + { + bar.b = foo.b; + } +-/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *23, *(23|7), *9" { target arc-*-* } } } */ ++/* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *7, *7, *9" { target arc-*-* } } } */ + /* { dg-final { scan-assembler "movb\[ \t\]+r\[0-5\]+, *r\[0-5\]+, *r\[0-5\]+, *0, *0, *9" { target arceb-*-* } } } */ +diff --git a/gcc/testsuite/gcc.target/arc/movh_cl-1.c b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +index 13c0f3434433..9c0036c1a3a8 100644 +--- a/gcc/testsuite/gcc.target/arc/movh_cl-1.c ++++ b/gcc/testsuite/gcc.target/arc/movh_cl-1.c +@@ -11,6 +11,9 @@ struct thing + { + unsigned a : 1; + unsigned b : 1; ++ unsigned c : 28; ++ unsigned d : 1; ++ unsigned e : 1; + }; + }; + }; +@@ -25,4 +28,12 @@ blah () + func (xx.raw); + } + ++void ++woof () ++{ ++ struct thing xx; ++ xx.d = xx.e = 1; ++ func (xx.raw); ++} ++ + /* { dg-final { scan-assembler "movh\.cl r\[0-9\]+,0xc0000000>>16" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0067-ARC-Make-lp_count-reg-fix-for-ARC600.patch b/toolchain/gcc/patches/6.3.0/0067-ARC-Make-lp_count-reg-fix-for-ARC600.patch new file mode 100644 index 0000000..b48cf73 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0067-ARC-Make-lp_count-reg-fix-for-ARC600.patch @@ -0,0 +1,53 @@ +From 8f2a8a15e09af99256f43ad2b7d3b5de8f317421 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 21 Nov 2016 16:44:46 +0100 +Subject: [PATCH 67/89] [ARC] Make lp_count reg fix for ARC600. + +gcc/ +2016-11-21 Claudiu Zissulescu + + * config/arc/arc.h (TARGET_LP_WR_INTERLOCK): Delete. + * config/arc/arc.c (arc_conditional_register_usage): Remove + TARGET_LP_WR_INTERLOCK condition. +--- + gcc/config/arc/arc.c | 9 +++++---- + gcc/config/arc/arc.h | 3 --- + 2 files changed, 5 insertions(+), 7 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 6500e3e21f05..7af55d351074 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1626,10 +1626,11 @@ arc_conditional_register_usage (void) + However, we can't actually use this approach, because for ARC the + delay slot scheduling pass is active, which runs after + machine_dependent_reorg. */ +- if (TARGET_ARC600) +- CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT); +- else if (!TARGET_LP_WR_INTERLOCK) +- fixed_regs[LP_COUNT] = 1; ++ if (TARGET_ARC600_FAMILY) ++ { ++ CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT); ++ fixed_regs[LP_COUNT] = 1; ++ } + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (!call_used_regs[regno]) + CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno); +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index e071946d8be5..1d256ca13f60 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1599,9 +1599,6 @@ enum + /* ARC600, ARC601 and ARC700 feature macro. */ + #define TARGET_ARCOMPACT_FAMILY \ + (TARGET_ARC600 || TARGET_ARC601 || TARGET_ARC700) +-/* Loop count register can be read in very next instruction after has +- been written to by an ordinary instruction. */ +-#define TARGET_LP_WR_INTERLOCK (!TARGET_ARC600_FAMILY) + + /* FPU defines. */ + /* Any FPU support. */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0068-ARC-Add-support-for-advanced-mpy-mac-instructions.patch b/toolchain/gcc/patches/6.3.0/0068-ARC-Add-support-for-advanced-mpy-mac-instructions.patch new file mode 100644 index 0000000..5aa6c8d --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0068-ARC-Add-support-for-advanced-mpy-mac-instructions.patch @@ -0,0 +1,376 @@ +From 9f35b6bc524f3ddb8b41ffde58c81d284931ad4e Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 8 Dec 2016 11:59:07 +0100 +Subject: [PATCH 68/89] [ARC] Add support for advanced mpy/mac instructions. + +gcc/ +2016-12-08 Claudiu Zissulescu + + * config/arc/arc.c (arc_conditional_register_usage): Handle ACCL, + ACCH registers. + * config/arc/arc.md (mulsidi3): Use advanced mpy instructions when + available. + (umulsidi3): Likewise. + (mulsidi3_700): Disable this pattern when we have advanced mpy + instructions. + (umulsidi3_700): Likewise. + (maddsidi4): New pattern. + (macd, mac, mac_r, umaddsidi4, macdu, macu, macu_r): Likewise. + (mpyd_arcv2hs, mpyd_imm_arcv2hs, mpydu_arcv2hs): Likewise. + (mpydu_imm_arcv2hs): Likewise. + * config/arc/predicates.md (accl_operand): New predicate. +--- + gcc/config/arc/arc.c | 7 +- + gcc/config/arc/arc.md | 266 ++++++++++++++++++++++++++++++++++++++++++- + gcc/config/arc/predicates.md | 5 + + 3 files changed, 274 insertions(+), 4 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 7af55d351074..e7a20e8ce08e 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1764,8 +1764,9 @@ arc_conditional_register_usage (void) + arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS; + + /*ARCV2 Accumulator. */ +- if (TARGET_V2 +- && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED)) ++ if ((TARGET_V2 ++ && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED)) ++ || TARGET_PLUS_DMPY) + { + arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS; + arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS; +@@ -1773,6 +1774,8 @@ arc_conditional_register_usage (void) + SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO); + SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO); + SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO); ++ SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO); ++ SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO); + arc_hard_regno_mode_ok[ACC_REG_FIRST] = D_MODES; + } + } +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 992a114f3a38..5e9dbf15f3a9 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -2114,6 +2114,18 @@ + "TARGET_ANY_MPY" + " + { ++ if (TARGET_PLUS_MACD) ++ { ++ if (CONST_INT_P (operands[2])) ++ { ++ emit_insn (gen_mpyd_imm_arcv2hs (operands[0], operands[1], operands[2])); ++ } ++ else ++ { ++ emit_insn (gen_mpyd_arcv2hs (operands[0], operands[1], operands[2])); ++ } ++ DONE; ++ } + if (TARGET_MPY) + { + operands[2] = force_reg (SImode, operands[2]); +@@ -2194,7 +2206,7 @@ + [(set (match_operand:DI 0 "register_operand" "=&r") + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c")) + (sign_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] +- "TARGET_MPY" ++ "TARGET_MPY && !TARGET_PLUS_MACD" + "#" + "&& reload_completed" + [(const_int 0)] +@@ -2347,6 +2359,18 @@ + (zero_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] + "" + { ++ if (TARGET_PLUS_MACD) ++ { ++ if (CONST_INT_P (operands[2])) ++ { ++ emit_insn (gen_mpydu_imm_arcv2hs (operands[0], operands[1], operands[2])); ++ } ++ else ++ { ++ emit_insn (gen_mpydu_arcv2hs (operands[0], operands[1], operands[2])); ++ } ++ DONE; ++ } + if (TARGET_MPY) + { + operands[2] = force_reg (SImode, operands[2]); +@@ -2437,7 +2461,7 @@ + [(set (match_operand:DI 0 "dest_reg_operand" "=&r") + (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) + (zero_extend:DI (match_operand:SI 2 "extend_operand" "cL"))))] +- "TARGET_MPY" ++ "TARGET_MPY && !TARGET_PLUS_MACD" + "#" + "reload_completed" + [(const_int 0)] +@@ -6155,6 +6179,244 @@ + [(set (zero_extract:SI (match_dup 3) (match_dup 1) (match_dup 2)) + (zero_extract:SI (match_dup 0) (match_dup 1) (match_dup 2)))]) + ++;; MAC and DMPY instructions ++(define_insn_and_split "maddsidi4" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI ++ (mult:DI ++ (sign_extend:DI (match_operand:SI 1 "register_operand" "%r")) ++ (sign_extend:DI (match_operand:SI 2 "extend_operand" "ri"))) ++ (match_operand:DI 3 "register_operand" "r")))] ++ "TARGET_PLUS_DMPY" ++ "#" ++ "TARGET_PLUS_DMPY && reload_completed" ++ [(const_int 0)] ++ "{ ++ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); ++ emit_move_insn (acc_reg, operands[3]); ++ if (TARGET_PLUS_MACD) ++ emit_insn (gen_macd (operands[0], operands[1], operands[2])); ++ else ++ { ++ emit_insn (gen_mac (operands[1], operands[2])); ++ emit_move_insn (operands[0], acc_reg); ++ } ++ DONE; ++ }" ++ [(set_attr "type" "multi") ++ (set_attr "length" "36")]) ++ ++(define_insn "macd" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r") ++ (plus:DI ++ (mult:DI ++ (sign_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c")) ++ (sign_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,Cal"))) ++ (reg:DI ARCV2_ACC))) ++ (set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (sign_extend:DI (match_dup 1)) ++ (sign_extend:DI (match_dup 2))) ++ (reg:DI ARCV2_ACC)))] ++ "TARGET_PLUS_MACD" ++ "macd %0,%1,%2" ++ [(set_attr "length" "4,4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no,no") ++ (set_attr "cond" "canuse,nocond,nocond")]) ++ ++(define_insn "mac" ++ [(set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "%r,r")) ++ (sign_extend:DI (match_operand:SI 1 "extend_operand" "rI,i"))) ++ (reg:DI ARCV2_ACC)))] ++ "TARGET_PLUS_DMPY" ++ "mac 0,%0,%1" ++ [(set_attr "length" "4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_peephole2 ++ [(set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (sign_extend:DI (match_operand:SI 0 "register_operand" "")) ++ (sign_extend:DI (match_operand:SI 1 "extend_operand" ""))) ++ (reg:DI ARCV2_ACC))) ++ (set (match_operand:SI 2 "register_operand" "") ++ (match_operand:SI 3 "accl_operand" ""))] ++ "TARGET_PLUS_DMPY" ++ [(const_int 0)] ++ { ++ emit_insn (gen_mac_r (operands[2], operands[0], operands[1])); ++ DONE; ++ }) ++ ++(define_insn "mac_r" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (truncate:SI ++ (plus:DI ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r,r")) ++ (sign_extend:DI (match_operand:SI 2 "extend_operand" "rI,i"))) ++ (reg:DI ARCV2_ACC)))) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_DMPY" ++ "mac %0,%1,%2" ++ [(set_attr "length" "4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn_and_split "umaddsidi4" ++ [(set (match_operand:DI 0 "register_operand" "=r") ++ (plus:DI ++ (mult:DI ++ (zero_extend:DI (match_operand:SI 1 "register_operand" "%r")) ++ (zero_extend:DI (match_operand:SI 2 "extend_operand" "ri"))) ++ (match_operand:DI 3 "register_operand" "r")))] ++ "TARGET_PLUS_DMPY" ++ "#" ++ "TARGET_PLUS_DMPY && reload_completed" ++ [(const_int 0)] ++ "{ ++ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST); ++ emit_move_insn (acc_reg, operands[3]); ++ if (TARGET_PLUS_MACD) ++ emit_insn (gen_macdu (operands[0], operands[1], operands[2])); ++ else ++ { ++ emit_insn (gen_macu (operands[1], operands[2])); ++ emit_move_insn (operands[0], acc_reg); ++ } ++ DONE; ++ }" ++ [(set_attr "type" "multi") ++ (set_attr "length" "36")]) ++ ++(define_insn "macdu" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr,r,r") ++ (plus:DI ++ (mult:DI ++ (zero_extend:DI (match_operand:SI 1 "register_operand" "%0,c,c")) ++ (zero_extend:DI (match_operand:SI 2 "extend_operand" " c,cI,i"))) ++ (reg:DI ARCV2_ACC))) ++ (set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (zero_extend:DI (match_dup 1)) ++ (zero_extend:DI (match_dup 2))) ++ (reg:DI ARCV2_ACC)))] ++ "TARGET_PLUS_MACD" ++ "macdu %0,%1,%2" ++ [(set_attr "length" "4,4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no,no") ++ (set_attr "cond" "canuse,nocond,nocond")]) ++ ++(define_insn "macu" ++ [(set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "%r,r")) ++ (zero_extend:DI (match_operand:SI 1 "extend_operand" "rI,i"))) ++ (reg:DI ARCV2_ACC)))] ++ "TARGET_PLUS_DMPY" ++ "macu 0,%0,%1" ++ [(set_attr "length" "4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_peephole2 ++ [(set (reg:DI ARCV2_ACC) ++ (plus:DI ++ (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" "")) ++ (zero_extend:DI (match_operand:SI 1 "extend_operand" ""))) ++ (reg:DI ARCV2_ACC))) ++ (set (match_operand:SI 2 "register_operand" "") ++ (match_operand:SI 3 "accl_operand" ""))] ++ "TARGET_PLUS_DMPY" ++ [(const_int 0)] ++ { ++ emit_insn (gen_macu_r (operands[2], operands[0], operands[1])); ++ DONE; ++ }) ++ ++(define_insn "macu_r" ++ [(set (match_operand:SI 0 "register_operand" "=r,r") ++ (truncate:SI ++ (plus:DI ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%r,r")) ++ (zero_extend:DI (match_operand:SI 2 "extend_operand" "rI,i"))) ++ (reg:DI ARCV2_ACC)))) ++ (clobber (reg:DI ARCV2_ACC))] ++ "TARGET_PLUS_DMPY" ++ "macu %0,%1,%2" ++ [(set_attr "length" "4,8") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "no") ++ (set_attr "cond" "nocond")]) ++ ++(define_insn "mpyd_arcv2hs" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r") ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c")) ++ (sign_extend:DI (match_operand:SI 2 "register_operand" " c, c")))) ++ (set (reg:DI ARCV2_ACC) ++ (mult:DI ++ (sign_extend:DI (match_dup 1)) ++ (sign_extend:DI (match_dup 2))))] ++ "TARGET_PLUS_MACD" ++ "mpyd%? %0,%1,%2" ++ [(set_attr "length" "4,4") ++ (set_attr "iscompact" "false") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "mpyd_imm_arcv2hs" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r") ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c")) ++ (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal"))) ++ (set (reg:DI ARCV2_ACC) ++ (mult:DI (sign_extend:DI (match_dup 1)) ++ (match_dup 2)))] ++ "TARGET_PLUS_MACD" ++ "mpyd%? %0,%1,%2" ++ [(set_attr "length" "4,4,4,8,8") ++ (set_attr "iscompact" "false") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no,no,yes,no") ++ (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) ++ ++(define_insn "mpydu_arcv2hs" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r") ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c")) ++ (zero_extend:DI (match_operand:SI 2 "register_operand" " c, c")))) ++ (set (reg:DI ARCV2_ACC) ++ (mult:DI (zero_extend:DI (match_dup 1)) ++ (zero_extend:DI (match_dup 2))))] ++ "TARGET_PLUS_MACD" ++ "mpydu%? %0,%1,%2" ++ [(set_attr "length" "4,4") ++ (set_attr "iscompact" "false") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no") ++ (set_attr "cond" "canuse,nocond")]) ++ ++(define_insn "mpydu_imm_arcv2hs" ++ [(set (match_operand:DI 0 "even_register_operand" "=Rcr, r,r,Rcr, r") ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" " 0, c,0, 0, c")) ++ (match_operand 2 "immediate_operand" " L, L,I,Cal,Cal"))) ++ (set (reg:DI ARCV2_ACC) ++ (mult:DI (zero_extend:DI (match_dup 1)) ++ (match_dup 2)))] ++ "TARGET_PLUS_MACD" ++ "mpydu%? %0,%1,%2" ++ [(set_attr "length" "4,4,4,8,8") ++ (set_attr "iscompact" "false") ++ (set_attr "type" "multi") ++ (set_attr "predicable" "yes,no,no,yes,no") ++ (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 5c95c207758d..5dae7534a20c 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -678,6 +678,11 @@ + (and (match_code "reg") + (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 58 : 59)"))) + ++(define_predicate "accl_operand" ++ (and (match_code "reg") ++ (match_test "REGNO (op) == (TARGET_BIG_ENDIAN ? 59 : 58)") ++ (match_test "TARGET_V2"))) ++ + ; Unfortunately, we can not allow a const_int_operand before reload, because + ; reload needs a non-void mode to guide it how to reload the inside of a + ; {sign_}extend. +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0069-ARC-Fix-typo-dmpyh-pattern.patch b/toolchain/gcc/patches/6.3.0/0069-ARC-Fix-typo-dmpyh-pattern.patch new file mode 100644 index 0000000..e53a06e --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0069-ARC-Fix-typo-dmpyh-pattern.patch @@ -0,0 +1,29 @@ +From 29fb6afa2f9d6b9ccfe51398ff073b565e48a1ca Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 8 Dec 2016 12:01:06 +0100 +Subject: [PATCH 69/89] [ARC] Fix typo dmpyh pattern + +gcc/ +2016-12-08 Claudiu Zissulescu + + * config/arc/simdext.md (dmpyh): Fix typo. +--- + gcc/config/arc/simdext.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md +index 51869e367726..95e9d2c038ff 100644 +--- a/gcc/config/arc/simdext.md ++++ b/gcc/config/arc/simdext.md +@@ -1544,7 +1544,7 @@ + (SE:SI (vec_select:HI (match_dup 1) (parallel [(const_int 1)]))) + (SE:SI (vec_select:HI (match_dup 2) (parallel [(const_int 1)])))))))] + "TARGET_PLUS_DMPY" +- "dmpy%? %0, %1, %2" ++ "dmpyh%? %0, %1, %2" + [(set_attr "length" "4") + (set_attr "type" "multi") + (set_attr "predicable" "yes,no") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0070-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch b/toolchain/gcc/patches/6.3.0/0070-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch new file mode 100644 index 0000000..c5c1ab7 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0070-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch @@ -0,0 +1,120 @@ +From 61a6f04014bfb4171fc26da5110343c47daff509 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 8 Dec 2016 16:30:39 +0100 +Subject: [PATCH 70/89] [ARC] Differentiate between ARCv1 and ARCv2 'h'-reg + class for CMP insns. + +gcc/ +2016-12-08 Claudiu Zissulescu + + * config/arc/arc.md (cmpsi_cc_insn_mixed): Use 'h' register + constraint. + (cmpsi_cc_c_insn): Likewise. + (cbranchsi4_scratch): Compute proper instruction length using + compact_hreg_operand. + * config/arc/predicates.md (compact_hreg_operand): New predicate. +--- + gcc/config/arc/arc.md | 28 ++++++++++++++++------------ + gcc/config/arc/predicates.md | 13 +++++++++++++ + 2 files changed, 29 insertions(+), 12 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 5e9dbf15f3a9..b70bd20e2fe7 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -3439,15 +3439,16 @@ + ;; modifed cc user if second, but not first operand is a compact register. + (define_insn "cmpsi_cc_insn_mixed" + [(set (reg:CC CC_REG) +- (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q, h, c, c,qRcq,c") +- (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI,cL, Cal,Cal")))] ++ (compare:CC (match_operand:SI 0 "register_operand" "Rcq#q,Rcqq, h, c, c,qRcq,c") ++ (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI,cL, Cal,Cal")))] + "" + "cmp%? %0,%B1%&" + [(set_attr "type" "compare") +- (set_attr "iscompact" "true,true,false,false,true_limm,false") +- (set_attr "predicable" "no,no,no,yes,no,yes") ++ (set_attr "iscompact" "true,true,true,false,false,true_limm,false") ++ (set_attr "predicable" "no,no,no,no,yes,no,yes") + (set_attr "cond" "set") +- (set_attr "length" "*,*,4,4,*,8")]) ++ (set_attr "length" "*,*,*,4,4,*,8") ++ (set_attr "cpu_facility" "av1,av2,*,*,*,*,*")]) + + (define_insn "*cmpsi_cc_zn_insn" + [(set (reg:CC_ZN CC_REG) +@@ -3523,14 +3524,15 @@ + + (define_insn "*cmpsi_cc_c_insn" + [(set (reg:CC_C CC_REG) +- (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq, h, c,Rcqq, c") +- (match_operand:SI 1 "nonmemory_operand" "cO,Cm1,cI, Cal,Cal")))] ++ (compare:CC_C (match_operand:SI 0 "register_operand" "Rcqq,Rcqq, h, c,Rcqq, c") ++ (match_operand:SI 1 "nonmemory_operand" "cO, hO,Cm1,cI, Cal,Cal")))] + "" + "cmp%? %0,%S1%&" + [(set_attr "type" "compare") +- (set_attr "iscompact" "true,true,false,true_limm,false") ++ (set_attr "iscompact" "true,true,true,false,true_limm,false") + (set_attr "cond" "set") +- (set_attr "length" "*,*,4,*,8")]) ++ (set_attr "length" "*,*,*,4,*,8") ++ (set_attr "cpu_facility" "av1,av2,*,*,*,*")]) + + ;; Next come the scc insns. + +@@ -4821,7 +4823,7 @@ + case 8: if (!brcc_nolimm_operator (operands[0], VOIDmode)) + return \"br%d0%* %1, %B2, %^%l3\"; + case 6: case 10: +- case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%&;br%d0 out of range\"; ++ case 12:return \"cmp%? %1, %B2\\n\\tb%d0%* %^%l3%& ;br%d0 out of range\"; + default: fprintf (stderr, \"unexpected length %d\\n\", get_attr_length (insn)); fflush (stderr); gcc_unreachable (); + } + " +@@ -4851,13 +4853,15 @@ + (minus (const_int 244) + (symbol_ref "get_attr_delay_slot_length (insn)")))) + (const_int 4) +- (match_operand:SI 1 "compact_register_operand" "") ++ (and (match_operand:SI 1 "compact_register_operand" "") ++ (match_operand:SI 2 "compact_hreg_operand" "")) + (const_int 6)] + (const_int 8))] + (cond [(and (ge (minus (match_dup 3) (pc)) (const_int -256)) + (le (minus (match_dup 3) (pc)) (const_int 244))) + (const_int 8) +- (match_operand:SI 1 "compact_register_operand" "") ++ (and (match_operand:SI 1 "compact_register_operand" "") ++ (match_operand:SI 2 "compact_hreg_operand" "")) + (const_int 10)] + (const_int 12)))) + (set (attr "iscompact") +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index 5dae7534a20c..a6b81a147897 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -189,6 +189,19 @@ + } + ) + ++(define_predicate "compact_hreg_operand" ++ (match_code "reg, subreg") ++ { ++ if ((GET_MODE (op) != mode) && (mode != VOIDmode)) ++ return 0; ++ ++ return (GET_CODE (op) == REG) ++ && (REGNO (op) >= FIRST_PSEUDO_REGISTER ++ || (TARGET_V2 && REGNO (op) <= 31 && REGNO (op) != 30) ++ || !TARGET_V2); ++ } ++) ++ + ;; Return true if OP is an acceptable memory operand for ARCompact + ;; 16-bit store instructions + (define_predicate "compact_store_memory_operand" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0071-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch b/toolchain/gcc/patches/6.3.0/0071-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch new file mode 100644 index 0000000..90efbd9 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0071-ARC-Differentiate-between-ARCv1-and-ARCv2-h-reg-clas.patch @@ -0,0 +1,89 @@ +From 81486ae68c06bded143b9510fb29e83f90edbd9b Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Thu, 8 Dec 2016 16:33:54 +0100 +Subject: [PATCH 71/89] [ARC] Differentiate between ARCv1 and ARCv2 'h'-reg + class for ADD insns. + +gcc/ +2016-12-08 Claudiu Zissulescu + + * config/arc/arc.c (arc_output_addsi): Check for h-register class + when emitting short ADD instructions. +--- + gcc/config/arc/arc.c | 42 +++++++++++++++++++++++++++--------------- + 1 file changed, 27 insertions(+), 15 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index e7a20e8ce08e..e3bcfb883351 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -7706,6 +7706,10 @@ arc_output_addsi (rtx *operands, bool cond_p, bool output_p) + int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1])); + int ret = 0; + ++#define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \ ++ && REGNO (OP) != 30) \ ++ || !TARGET_V2)) ++ + #define ADDSI_OUTPUT1(FORMAT) do {\ + if (output_p) \ + output_asm_insn (FORMAT, operands);\ +@@ -7728,32 +7732,40 @@ arc_output_addsi (rtx *operands, bool cond_p, bool output_p) + but add1 r0,sp,35 doesn't. */ + && (!output_p || (get_attr_length (current_output_insn) & 2))) + { ++ /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h ++ patterns. */ + if (short_p +- && (REG_P (operands[2]) +- ? (match || satisfies_constraint_Rcq (operands[2])) +- : (unsigned) intval <= (match ? 127 : 7))) +- ADDSI_OUTPUT1 ("add%? %0,%1,%2"); +- if (short_0 && REG_P (operands[1]) && match2) +- ADDSI_OUTPUT1 ("add%? %0,%2,%1"); ++ && ((REG_H_P (operands[2]) ++ && (match || satisfies_constraint_Rcq (operands[2]))) ++ || (CONST_INT_P (operands[2]) ++ && ((unsigned) intval <= (match ? 127 : 7))))) ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1"); ++ ++ /* Generate add_s b,b,h patterns. */ ++ if (short_0 && match2 && REG_H_P (operands[1])) ++ ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2"); ++ ++ /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */ + if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM) + && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124)) +- ADDSI_OUTPUT1 ("add%? %0,%1,%2"); ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3"); + + if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7)) + || (REGNO (operands[0]) == STACK_POINTER_REGNUM + && match && !(neg_intval & ~124))) +- ADDSI_OUTPUT1 ("sub%? %0,%1,%n2"); ++ ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4"); + +- if (REG_P(operands[0]) && REG_P(operands[1]) +- && (REGNO(operands[0]) <= 31) && (REGNO(operands[0]) == REGNO(operands[1])) +- && CONST_INT_P (operands[2]) && ( (intval>= -1) && (intval <= 6))) +- ADDSI_OUTPUT1 ("add%? %0,%1,%2"); ++ /* Generate add_s h,h,s3 patterns. */ ++ if (REG_H_P (operands[0]) && match && TARGET_V2 ++ && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6))) ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5"); + +- if (TARGET_CODE_DENSITY && REG_P(operands[0]) && REG_P(operands[1]) +- && ((REGNO(operands[0]) == 0) || (REGNO(operands[0]) == 1)) ++ /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */ ++ if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1]) ++ && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1)) + && satisfies_constraint_Rcq (operands[1]) + && satisfies_constraint_L (operands[2])) +- ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3"); ++ ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6"); + } + + /* Now try to emit a 32 bit insn without long immediate. */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0072-ARC-Allow-extension-core-registers-to-be-used-for-ad.patch b/toolchain/gcc/patches/6.3.0/0072-ARC-Allow-extension-core-registers-to-be-used-for-ad.patch new file mode 100644 index 0000000..9584159 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0072-ARC-Allow-extension-core-registers-to-be-used-for-ad.patch @@ -0,0 +1,60 @@ +From b435891f00b8e8d31a49876f7246ad22e054321c Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 9 Dec 2016 13:29:51 +0100 +Subject: [PATCH 72/89] [ARC] Allow extension core registers to be used for + addresses. + +gcc/ +2016-12-09 Claudiu Zissulescu + + * config/arc/arc.h (REGNO_OK_FOR_BASE_P): Consider also extension + core registers. + (REG_OK_FOR_INDEX_P_NONSTRICT): Likewise. + (REG_OK_FOR_BASE_P_NONSTRICT): Likewise. +--- + gcc/config/arc/arc.h | 20 +++++++++----------- + 1 file changed, 9 insertions(+), 11 deletions(-) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 1d256ca13f60..92c1ce858ff2 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -611,7 +611,8 @@ extern enum reg_class arc_regno_reg_class[]; + #define REGNO_OK_FOR_BASE_P(REGNO) \ + ((REGNO) < 29 || ((REGNO) == ARG_POINTER_REGNUM) || ((REGNO) == 63) \ + || ((unsigned) reg_renumber[REGNO] < 29) \ +- || ((unsigned) (REGNO) == (unsigned) arc_tp_regno)) ++ || ((unsigned) (REGNO) == (unsigned) arc_tp_regno) \ ++ || (fixed_regs[REGNO] == 0 && IN_RANGE (REGNO, 32, 59))) + + #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) + +@@ -893,18 +894,15 @@ extern int arc_initial_elimination_offset(int from, int to); + + /* Nonzero if X is a hard reg that can be used as an index + or if it is a pseudo reg. */ +-#define REG_OK_FOR_INDEX_P_NONSTRICT(X) \ +-((unsigned) REGNO (X) >= FIRST_PSEUDO_REGISTER || \ +- (unsigned) REGNO (X) < 29 || \ +- (unsigned) REGNO (X) == 63 || \ +- (unsigned) REGNO (X) == ARG_POINTER_REGNUM) ++#define REG_OK_FOR_INDEX_P_NONSTRICT(X) \ ++ ((unsigned) REGNO (X) >= FIRST_PSEUDO_REGISTER \ ++ || REGNO_OK_FOR_BASE_P (REGNO (X))) ++ + /* Nonzero if X is a hard reg that can be used as a base reg + or if it is a pseudo reg. */ +-#define REG_OK_FOR_BASE_P_NONSTRICT(X) \ +-((unsigned) REGNO (X) >= FIRST_PSEUDO_REGISTER || \ +- (unsigned) REGNO (X) < 29 || \ +- (unsigned) REGNO (X) == 63 || \ +- (unsigned) REGNO (X) == ARG_POINTER_REGNUM) ++#define REG_OK_FOR_BASE_P_NONSTRICT(X) \ ++ ((unsigned) REGNO (X) >= FIRST_PSEUDO_REGISTER \ ++ || REGNO_OK_FOR_BASE_P (REGNO (X))) + + /* Nonzero if X is a hard reg that can be used as an index. */ + #define REG_OK_FOR_INDEX_P_STRICT(X) REGNO_OK_FOR_INDEX_P (REGNO (X)) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0073-ARC-Make-D0-D1-double-regs-fix-when-not-used.patch b/toolchain/gcc/patches/6.3.0/0073-ARC-Make-D0-D1-double-regs-fix-when-not-used.patch new file mode 100644 index 0000000..61c7189 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0073-ARC-Make-D0-D1-double-regs-fix-when-not-used.patch @@ -0,0 +1,33 @@ +From 10c17115e6a75067cb05a4f9ad9b0047af2cb476 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 9 Dec 2016 13:33:44 +0100 +Subject: [PATCH 73/89] [ARC] Make D0, D1 double regs fix when not used. + +gcc/ +2016-12-09 Claudiu Zissulescu + + * config/arc/arc.c (arc_conditional_register_usage): Make D0, D1 + double regs fix when not used. +--- + gcc/config/arc/arc.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index e3bcfb883351..27a198233381 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1736,6 +1736,11 @@ arc_conditional_register_usage (void) + arc_regno_reg_class[42] = ALL_REGS; + arc_regno_reg_class[43] = ALL_REGS; + ++ fixed_regs[40] = 1; ++ fixed_regs[41] = 1; ++ fixed_regs[42] = 1; ++ fixed_regs[43] = 1; ++ + arc_hard_regno_mode_ok[40] = 0; + arc_hard_regno_mode_ok[42] = 0; + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0074-ARC-Use-ACCL-ACCH-registers-whenever-they-are-availa.patch b/toolchain/gcc/patches/6.3.0/0074-ARC-Use-ACCL-ACCH-registers-whenever-they-are-availa.patch new file mode 100644 index 0000000..3519835 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0074-ARC-Use-ACCL-ACCH-registers-whenever-they-are-availa.patch @@ -0,0 +1,36 @@ +From 931d11c96f19ddfc27f3d11c04cd2a7831fa7499 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Fri, 9 Dec 2016 13:36:47 +0100 +Subject: [PATCH 74/89] [ARC] Use ACCL, ACCH registers whenever they are + available. + +gcc/ +2016-12-09 Claudiu Zissulescu + + * config/arc/arc.c (arc_conditional_register_usage): Use ACCL, + ACCH registers whenever they are available. +--- + gcc/config/arc/arc.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 27a198233381..111577eafa10 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1781,6 +1781,13 @@ arc_conditional_register_usage (void) + SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO); + SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO); + SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO); ++ SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCL_REGNO); ++ SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCH_REGNO); ++ ++ /* Allow the compiler to freely use them. */ ++ fixed_regs[ACCL_REGNO] = 0; ++ fixed_regs[ACCH_REGNO] = 0; ++ + arc_hard_regno_mode_ok[ACC_REG_FIRST] = D_MODES; + } + } +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0075-ARC-Avoid-use-of-hard-registers-before-reg-alloc.patch b/toolchain/gcc/patches/6.3.0/0075-ARC-Avoid-use-of-hard-registers-before-reg-alloc.patch new file mode 100644 index 0000000..0ccffd2 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0075-ARC-Avoid-use-of-hard-registers-before-reg-alloc.patch @@ -0,0 +1,236 @@ +From 99e3345f33d56c5a378f7181afa36961381ffcc6 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 12 Dec 2016 16:17:26 +0100 +Subject: [PATCH 75/89] [ARC] Avoid use of hard registers before reg-alloc. + +gcc/ +2016-12-12 Claudiu Zissulescu + + * config/arc/arc.md (mulsi3): Avoid use of hard registers before + reg-alloc when having mul64 or mul32x16 instructions. + (mulsidi3): Likewise. + (umulsidi3): Likewise. + (mulsi32x16): New pattern. + (mulsi64): Likewise. + (mulsidi64): Likewise. + (umulsidi64): Likewise. +--- + gcc/config/arc/arc.md | 145 +++++++++++++++++++++++++++++++++++--------------- + 1 file changed, 101 insertions(+), 44 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index b70bd20e2fe7..c2bcfb530ad7 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -1897,29 +1897,15 @@ + } + else if (TARGET_MUL64_SET) + { +- emit_insn (gen_mulsi_600 (operands[1], operands[2], +- gen_mlo (), gen_mhi ())); +- emit_move_insn (operands[0], gen_mlo ()); +- DONE; ++ operands[0] = force_reg (SImode, operands[0]); ++ emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2])); ++ DONE; + } + else if (TARGET_MULMAC_32BY16_SET) + { +- if (immediate_operand (operands[2], SImode) +- && INTVAL (operands[2]) >= 0 +- && INTVAL (operands[2]) <= 65535) +- { +- emit_insn (gen_umul_600 (operands[1], operands[2], +- gen_acc2 (), gen_acc1 ())); +- emit_move_insn (operands[0], gen_acc2 ()); +- DONE; +- } +- operands[2] = force_reg (SImode, operands[2]); +- emit_insn (gen_umul_600 (operands[1], operands[2], +- gen_acc2 (), gen_acc1 ())); +- emit_insn (gen_mac_600 (operands[1], operands[2], +- gen_acc2 (), gen_acc1 ())); +- emit_move_insn (operands[0], gen_acc2 ()); +- DONE; ++ operands[0] = force_reg (SImode, operands[0]); ++ emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2])); ++ DONE; + } + else + { +@@ -1931,6 +1917,34 @@ + } + }) + ++(define_insn_and_split "mulsi32x16" ++ [(set (match_operand:SI 0 "register_operand" "=w") ++ (mult:SI (match_operand:SI 1 "register_operand" "%c") ++ (match_operand:SI 2 "nonmemory_operand" "ci")))] ++ "TARGET_MULMAC_32BY16_SET" ++ "#" ++ "TARGET_MULMAC_32BY16_SET && reload_completed" ++ [(const_int 0)] ++ { ++ if (immediate_operand (operands[2], SImode) ++ && INTVAL (operands[2]) >= 0 ++ && INTVAL (operands[2]) <= 65535) ++ { ++ emit_insn (gen_umul_600 (operands[1], operands[2], ++ gen_acc2 (), gen_acc1 ())); ++ emit_move_insn (operands[0], gen_acc2 ()); ++ DONE; ++ } ++ emit_insn (gen_umul_600 (operands[1], operands[2], ++ gen_acc2 (), gen_acc1 ())); ++ emit_insn (gen_mac_600 (operands[1], operands[2], ++ gen_acc2 (), gen_acc1 ())); ++ emit_move_insn (operands[0], gen_acc2 ()); ++ DONE; ++ } ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++ + ; mululw conditional execution without a LIMM clobbers an input register; + ; we'd need a different pattern to describe this. + ; To make the conditional execution valid for the LIMM alternative, we +@@ -1968,6 +1982,23 @@ + (set_attr "predicable" "no, no, yes") + (set_attr "cond" "nocond, canuse_limm, canuse")]) + ++(define_insn_and_split "mulsi64" ++ [(set (match_operand:SI 0 "register_operand" "=w") ++ (mult:SI (match_operand:SI 1 "register_operand" "%c") ++ (match_operand:SI 2 "nonmemory_operand" "ci")))] ++ "TARGET_MUL64_SET" ++ "#" ++ "TARGET_MUL64_SET && reload_completed" ++ [(const_int 0)] ++{ ++ emit_insn (gen_mulsi_600 (operands[1], operands[2], ++ gen_mlo (), gen_mhi ())); ++ emit_move_insn (operands[0], gen_mlo ()); ++ DONE; ++} ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++ + (define_insn "mulsi_600" + [(set (match_operand:SI 2 "mlo_operand" "") + (mult:SI (match_operand:SI 0 "register_operand" "%Rcq#q,c,c,c") +@@ -2112,8 +2143,7 @@ + (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "")) + (sign_extend:DI (match_operand:SI 2 "nonmemory_operand" ""))))] + "TARGET_ANY_MPY" +-" +-{ ++ { + if (TARGET_PLUS_MACD) + { + if (CONST_INT_P (operands[2])) +@@ -2144,17 +2174,29 @@ + emit_insn (gen_mulsidi_600 (operands[0], operands[1], operands[2])); + DONE; + } +- else if (TARGET_MULMAC_32BY16_SET) +- { +- rtx result_hi = gen_highpart(SImode, operands[0]); +- rtx result_low = gen_lowpart(SImode, operands[0]); ++ operands[2] = force_reg (SImode, operands[2]); ++ }) ++ ++(define_insn_and_split "mulsidi64" ++ [(set (match_operand:DI 0 "register_operand" "=w") ++ (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%c")) ++ (sign_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))] ++ "TARGET_MULMAC_32BY16_SET" ++ "#" ++ "TARGET_MULMAC_32BY16_SET && reload_completed" ++ [(const_int 0)] ++ { ++ rtx result_hi = gen_highpart (SImode, operands[0]); ++ rtx result_low = gen_lowpart (SImode, operands[0]); ++ ++ emit_insn (gen_mul64_600 (operands[1], operands[2])); ++ emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2])); ++ emit_move_insn (result_low, gen_acc2 ()); ++ DONE; ++ } ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) + +- emit_insn (gen_mul64_600 (operands[1], operands[2])); +- emit_insn (gen_mac64_600 (result_hi, operands[1], operands[2])); +- emit_move_insn (result_low, gen_acc2 ()); +- DONE; +- } +-}") + + (define_insn "mul64_600" + [(set (reg:DI 56) +@@ -2385,20 +2427,14 @@ + } + else if (TARGET_MUL64_SET) + { +- emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2])); ++ operands[2] = force_reg (SImode, operands[2]); ++ emit_insn (gen_umulsidi_600 (operands[0], operands[1], operands[2])); + DONE; + } + else if (TARGET_MULMAC_32BY16_SET) + { +- rtx result_hi = gen_reg_rtx (SImode); +- rtx result_low = gen_reg_rtx (SImode); +- +- result_hi = gen_highpart(SImode , operands[0]); +- result_low = gen_lowpart(SImode , operands[0]); +- +- emit_insn (gen_umul64_600 (operands[1], operands[2])); +- emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2])); +- emit_move_insn (result_low, gen_acc2 ()); ++ operands[2] = force_reg (SImode, operands[2]); ++ emit_insn (gen_umulsidi64 (operands[0], operands[1], operands[2])); + DONE; + } + else +@@ -2411,6 +2447,29 @@ + } + }) + ++(define_insn_and_split "umulsidi64" ++ [(set (match_operand:DI 0 "register_operand" "=w") ++ (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%c")) ++ (zero_extend:DI (match_operand:SI 2 "extend_operand" "ci"))))] ++ "TARGET_MULMAC_32BY16_SET" ++ "#" ++ "TARGET_MULMAC_32BY16_SET && reload_completed" ++ [(const_int 0)] ++ { ++ rtx result_hi; ++ rtx result_low; ++ ++ result_hi = gen_highpart (SImode, operands[0]); ++ result_low = gen_lowpart (SImode, operands[0]); ++ ++ emit_insn (gen_umul64_600 (operands[1], operands[2])); ++ emit_insn (gen_umac64_600 (result_hi, operands[1], operands[2])); ++ emit_move_insn (result_low, gen_acc2 ()); ++ DONE; ++ } ++ [(set_attr "type" "multi") ++ (set_attr "length" "8")]) ++ + (define_insn "umul64_600" + [(set (reg:DI 56) + (mult:DI (zero_extend:DI (match_operand:SI 0 "register_operand" +@@ -2454,8 +2513,6 @@ + (set_attr "predicable" "no,no,yes") + (set_attr "cond" "nocond, canuse_limm, canuse")]) + +- +- + ;; DI <- DI(unsigned SI) * DI(unsigned SI) + (define_insn_and_split "umulsidi3_700" + [(set (match_operand:DI 0 "dest_reg_operand" "=&r") +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0076-ARC-Allow-r30-to-be-used-by-the-reg-alloc.patch b/toolchain/gcc/patches/6.3.0/0076-ARC-Allow-r30-to-be-used-by-the-reg-alloc.patch new file mode 100644 index 0000000..c0f0fa0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0076-ARC-Allow-r30-to-be-used-by-the-reg-alloc.patch @@ -0,0 +1,52 @@ +From 1d20df0c6321747a74b3e7132cc91954511aa840 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 12 Dec 2016 16:20:37 +0100 +Subject: [PATCH 76/89] [ARC] Allow r30 to be used by the reg-alloc. + +gcc/ +2016-12-12 Claudiu Zissulescu + + * config/arc/arc.c (arc_conditional_register_usage): Allow r30 to + be used by the reg-alloc. +--- + gcc/config/arc/arc.c | 9 ++++++++- + gcc/config/arc/arc.h | 3 ++- + 2 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 111577eafa10..56edc6fe9152 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -1530,7 +1530,14 @@ arc_conditional_register_usage (void) + /* For ARCv2 the core register set is changed. */ + strcpy (rname29, "ilink"); + strcpy (rname30, "r30"); +- fixed_regs[30] = call_used_regs[30] = 1; ++ call_used_regs[30] = 1; ++ fixed_regs[30] = 0; ++ ++ arc_regno_reg_class[30] = WRITABLE_CORE_REGS; ++ SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30); ++ SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30); ++ SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30); ++ SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30); + } + + if (TARGET_MUL64_SET) +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 92c1ce858ff2..1f0f4989c239 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -612,7 +612,8 @@ extern enum reg_class arc_regno_reg_class[]; + ((REGNO) < 29 || ((REGNO) == ARG_POINTER_REGNUM) || ((REGNO) == 63) \ + || ((unsigned) reg_renumber[REGNO] < 29) \ + || ((unsigned) (REGNO) == (unsigned) arc_tp_regno) \ +- || (fixed_regs[REGNO] == 0 && IN_RANGE (REGNO, 32, 59))) ++ || (fixed_regs[REGNO] == 0 && IN_RANGE (REGNO, 32, 59)) \ ++ || ((REGNO) == 30 && fixed_regs[REGNO] == 0)) + + #define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_BASE_P(REGNO) + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0077-ARC-Cxx-Fix-calling-multiple-inheritances.patch b/toolchain/gcc/patches/6.3.0/0077-ARC-Cxx-Fix-calling-multiple-inheritances.patch new file mode 100644 index 0000000..31a1fff --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0077-ARC-Cxx-Fix-calling-multiple-inheritances.patch @@ -0,0 +1,55 @@ +From 47ff89b9b4d7ae2f75208d9a683225213e4cd1f0 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 13 Dec 2016 11:48:36 +0100 +Subject: [PATCH 77/89] [ARC] [Cxx] Fix calling multiple inheritances. + +The TARGET_ASM_OUTPUT_MI_THUNK hook doesn't take into account the +variant when we compile for PIC. + +gcc/ +2016-12-13 Claudiu Zissulescu + + * config/arc/arc.c (arc_output_mi_thunk): Emit PIC calls. +--- + gcc/config/arc/arc.c | 24 +++++++++++++++++++++--- + 1 file changed, 21 insertions(+), 3 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 56edc6fe9152..0105d45da9eb 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -6765,10 +6765,28 @@ arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED, + fnaddr = XEXP (DECL_RTL (function), 0); + + if (arc_is_longcall_p (fnaddr)) +- fputs ("\tj\t", file); ++ { ++ if (flag_pic) ++ { ++ asm_fprintf (file, "\tld\t%s, [pcl, @", ++ ARC_TEMP_SCRATCH_REG); ++ assemble_name (file, XSTR (fnaddr, 0)); ++ fputs ("@gotpc]\n", file); ++ asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG); ++ } ++ else ++ { ++ fputs ("\tj\t@", file); ++ assemble_name (file, XSTR (fnaddr, 0)); ++ } ++ } + else +- fputs ("\tb\t", file); +- assemble_name (file, XSTR (fnaddr, 0)); ++ { ++ fputs ("\tb\t@", file); ++ assemble_name (file, XSTR (fnaddr, 0)); ++ if (flag_pic) ++ fputs ("@plt\n", file); ++ } + fputc ('\n', file); + } + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0078-ARC-Addresses-can-use-long-immediate-for-offsets.patch b/toolchain/gcc/patches/6.3.0/0078-ARC-Addresses-can-use-long-immediate-for-offsets.patch new file mode 100644 index 0000000..06b520f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0078-ARC-Addresses-can-use-long-immediate-for-offsets.patch @@ -0,0 +1,94 @@ +From f3278e85c837f78f2d1fea7226c55f9c1f95fda7 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 13 Dec 2016 13:22:21 +0100 +Subject: [PATCH 78/89] [ARC] Addresses can use long immediate for offsets. + +gcc/ +2016-12-13 Claudiu Zissulescu + + * config/arc/arc.c (LEGITIMATE_OFFSET_ADDRESS_P): Delete macro. + (legitimate_offset_address_p): New function. + (arc_legitimate_address_p): Use above function. +--- + gcc/config/arc/arc.c | 44 +++++++++++++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 9 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 0105d45da9eb..1559c227da5f 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -77,13 +77,6 @@ static const char *arc_cpu_string = arc_cpu_name; + ? 0 \ + : -(-GET_MODE_SIZE (MODE) | -4) >> 1))) + +-#define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, INDEX, STRICT) \ +-(GET_CODE (X) == PLUS \ +- && RTX_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \ +- && ((INDEX && RTX_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)) \ +- && GET_MODE_SIZE ((MODE)) <= 4) \ +- || RTX_OK_FOR_OFFSET_P (MODE, XEXP (X, 1)))) +- + #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \ + (GET_CODE (X) == PLUS \ + && GET_CODE (XEXP (X, 0)) == MULT \ +@@ -285,6 +278,39 @@ bool arc_arc700 = false; + bool arc_arc600 = false; + bool arc_arc601 = false; + ++/* Check for constructions like REG + OFFS, where OFFS can be a ++ register, an immediate or an long immediate. */ ++ ++static bool ++legitimate_offset_address_p (enum machine_mode mode, rtx x, bool index, ++ bool strict) ++{ ++ if (GET_CODE (x) != PLUS) ++ return false; ++ ++ if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict))) ++ return false; ++ ++ /* Check for: [Rx + small offset] or [Rx + Ry]. */ ++ if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict)) ++ && GET_MODE_SIZE ((mode)) <= 4) ++ || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))) ++ return true; ++ ++ /* Check for [Rx + symbol]. */ ++ if (!flag_pic ++ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF) ++ /* Avoid this type of address for double or larger modes. */ ++ && (GET_MODE_SIZE (mode) <= 4) ++ /* Avoid small data which ends in something like GP + ++ symb@sda. */ ++ && (!SYMBOL_REF_SMALL_P (XEXP (x, 1)) ++ || TARGET_NO_SDATA_SET)) ++ return true; ++ ++ return false; ++} ++ + /* Implements target hook vector_mode_supported_p. */ + + static bool +@@ -5932,7 +5958,7 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict) + { + if (RTX_OK_FOR_BASE_P (x, strict)) + return true; +- if (LEGITIMATE_OFFSET_ADDRESS_P (mode, x, TARGET_INDEXED_LOADS, strict)) ++ if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict)) + return true; + if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict)) + return true; +@@ -5973,7 +5999,7 @@ arc_legitimate_address_p (machine_mode mode, rtx x, bool strict) + if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY) + && GET_CODE (XEXP ((x), 1)) == PLUS + && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0)) +- && LEGITIMATE_OFFSET_ADDRESS_P (QImode, XEXP (x, 1), ++ && legitimate_offset_address_p (QImode, XEXP (x, 1), + TARGET_AUTO_MODIFY_REG, strict)) + return true; + return false; +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0079-ARC-Add-support-for-naked-functions.patch b/toolchain/gcc/patches/6.3.0/0079-ARC-Add-support-for-naked-functions.patch new file mode 100644 index 0000000..193673e --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0079-ARC-Add-support-for-naked-functions.patch @@ -0,0 +1,512 @@ +From c959ad420906fb369b7d7fd0b7ca4e58231b496c Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 13 Dec 2016 15:57:12 +0100 +Subject: [PATCH 79/89] [ARC] Add support for naked functions. + +gcc/ +2016-12-13 Claudiu Zissulescu + Andrew Burgess + + * config/arc/arc-protos.h (arc_compute_function_type): Change prototype. + (arc_return_address_register): New function. + * config/arc/arc.c (arc_handle_fndecl_attribute): New function. + (arc_handle_fndecl_attribute): Add naked attribute. + (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Define. + (TARGET_WARN_FUNC_RETURN): Likewise. + (arc_allocate_stack_slots_for_args): New function. + (arc_warn_func_return): Likewise. + (machine_function): Change type fn_type. + (arc_compute_function_type): Consider new naked function type, + change function return type. + (arc_must_save_register): Adapt to handle new + arc_compute_function_type's return type. + (arc_expand_prologue): Likewise. + (arc_expand_epilogue): Likewise. + (arc_return_address_regs): Delete. + (arc_return_address_register): New function. + (arc_epilogue_uses): Use above function. + * config/arc/arc.h (arc_return_address_regs): Delete prototype. + (arc_function_type): Change encoding, add naked type. + (ARC_INTERRUPT_P): Change to handle the new encoding. + (ARC_FAST_INTERRUPT_P): Likewise. + (ARC_NORMAL_P): Define. + (ARC_NAKED_P): Likewise. + (arc_compute_function_type): Delete prototype. + * config/arc/arc.md (in_ret_delay_slot): Use + arc_return_address_register function. + (simple_return): Likewise. + (p_return_i): Likewise. + +gcc/testsuite +2016-12-13 Claudiu Zissulescu + Andrew Burgess + + * gcc.target/arc/naked-1.c: New file. + * gcc.target/arc/naked-2.c: Likewise. +--- + gcc/config/arc/arc-protos.h | 6 +- + gcc/config/arc/arc.c | 169 ++++++++++++++++++++++++--------- + gcc/config/arc/arc.h | 40 +++++--- + gcc/config/arc/arc.md | 10 +- + gcc/testsuite/gcc.target/arc/naked-1.c | 18 ++++ + gcc/testsuite/gcc.target/arc/naked-2.c | 26 +++++ + 6 files changed, 201 insertions(+), 68 deletions(-) + create mode 100644 gcc/testsuite/gcc.target/arc/naked-1.c + create mode 100644 gcc/testsuite/gcc.target/arc/naked-2.c + +diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h +index 7b8ceeaa13c1..83cf0f33aa78 100644 +--- a/gcc/config/arc/arc-protos.h ++++ b/gcc/config/arc/arc-protos.h +@@ -45,12 +45,10 @@ extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx); + extern void arc_split_compare_and_swap (rtx *); + extern void arc_expand_compare_and_swap (rtx *); + extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool); ++extern int arc_return_address_register (unsigned int); ++extern unsigned int arc_compute_function_type (struct function *); + #endif /* RTX_CODE */ + +-#ifdef TREE_CODE +-extern enum arc_function_type arc_compute_function_type (struct function *); +-#endif /* TREE_CODE */ +- + extern bool arc_ccfsm_branch_deleted_p (void); + extern void arc_ccfsm_record_branch_deleted (void); + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 1559c227da5f..6f21fc372516 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -210,6 +210,7 @@ static int rgf_banked_register_count; + static int get_arc_condition_code (rtx); + + static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *); ++static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *); + + /* Initialized arc_attribute_table to NULL since arc doesnot have any + machine specific supported attributes. */ +@@ -228,6 +229,9 @@ const struct attribute_spec arc_attribute_table[] = + /* And these functions are always known to reside within the 21 bit + addressing range of blcc. */ + { "short_call", 0, 0, false, true, true, NULL, false }, ++ /* Function which are not having the prologue and epilogue generated ++ by the compiler. */ ++ { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute, false }, + { NULL, 0, 0, false, false, false, NULL, false } + }; + static int arc_comp_type_attributes (const_tree, const_tree); +@@ -519,6 +523,12 @@ static void arc_finalize_pic (void); + #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true + #define TARGET_SPILL_CLASS arc_spill_class + ++#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS ++#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args ++ ++#undef TARGET_WARN_FUNC_RETURN ++#define TARGET_WARN_FUNC_RETURN arc_warn_func_return ++ + #include "target-def.h" + + #undef TARGET_ASM_ALIGNED_HI_OP +@@ -1865,6 +1875,42 @@ arc_handle_interrupt_attribute (tree *, tree name, tree args, int, + return NULL_TREE; + } + ++static tree ++arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED, ++ int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) ++{ ++ if (TREE_CODE (*node) != FUNCTION_DECL) ++ { ++ warning (OPT_Wattributes, "%qE attribute only applies to functions", ++ name); ++ *no_add_attrs = true; ++ } ++ ++ return NULL_TREE; ++} ++ ++/* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */ ++ ++static bool ++arc_allocate_stack_slots_for_args (void) ++{ ++ /* Naked functions should not allocate stack slots for arguments. */ ++ unsigned int fn_type = arc_compute_function_type (cfun); ++ ++ return !ARC_NAKED_P(fn_type); ++} ++ ++/* Implement `TARGET_WARN_FUNC_RETURN'. */ ++ ++static bool ++arc_warn_func_return (tree decl) ++{ ++ struct function *func = DECL_STRUCT_FUNCTION (decl); ++ unsigned int fn_type = arc_compute_function_type (func); ++ ++ return !ARC_NAKED_P (fn_type); ++} ++ + /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible, + and two if they are nearly compatible (which causes a warning to be + generated). */ +@@ -2368,7 +2414,7 @@ struct GTY (()) arc_frame_info + + typedef struct GTY (()) machine_function + { +- enum arc_function_type fn_type; ++ unsigned int fn_type; + struct arc_frame_info frame_info; + /* To keep track of unalignment caused by short insns. */ + int unalign; +@@ -2386,43 +2432,40 @@ typedef struct GTY (()) machine_function + The result is cached. To reset the cache at the end of a function, + call with DECL = NULL_TREE. */ + +-enum arc_function_type ++unsigned int + arc_compute_function_type (struct function *fun) + { +- tree decl = fun->decl; +- tree a; +- enum arc_function_type fn_type = fun->machine->fn_type; ++ tree attr, decl = fun->decl; ++ unsigned int fn_type = fun->machine->fn_type; + + if (fn_type != ARC_FUNCTION_UNKNOWN) + return fn_type; + +- /* Assume we have a normal function (not an interrupt handler). */ +- fn_type = ARC_FUNCTION_NORMAL; ++ /* Check if it is a naked function. */ ++ if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE) ++ fn_type |= ARC_FUNCTION_NAKED; ++ else ++ fn_type |= ARC_FUNCTION_NORMAL; + + /* Now see if this is an interrupt handler. */ +- for (a = DECL_ATTRIBUTES (decl); +- a; +- a = TREE_CHAIN (a)) +- { +- tree name = TREE_PURPOSE (a), args = TREE_VALUE (a); +- +- if (name == get_identifier ("interrupt") +- && list_length (args) == 1 +- && TREE_CODE (TREE_VALUE (args)) == STRING_CST) +- { +- tree value = TREE_VALUE (args); +- +- if (!strcmp (TREE_STRING_POINTER (value), "ilink1") +- || !strcmp (TREE_STRING_POINTER (value), "ilink")) +- fn_type = ARC_FUNCTION_ILINK1; +- else if (!strcmp (TREE_STRING_POINTER (value), "ilink2")) +- fn_type = ARC_FUNCTION_ILINK2; +- else if (!strcmp (TREE_STRING_POINTER (value), "firq")) +- fn_type = ARC_FUNCTION_FIRQ; +- else +- gcc_unreachable (); +- break; +- } ++ attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl)); ++ if (attr != NULL_TREE) ++ { ++ tree value, args = TREE_VALUE (attr); ++ ++ gcc_assert (list_length (args) == 1); ++ value = TREE_VALUE (args); ++ gcc_assert (TREE_CODE (value) == STRING_CST); ++ ++ if (!strcmp (TREE_STRING_POINTER (value), "ilink1") ++ || !strcmp (TREE_STRING_POINTER (value), "ilink")) ++ fn_type |= ARC_FUNCTION_ILINK1; ++ else if (!strcmp (TREE_STRING_POINTER (value), "ilink2")) ++ fn_type |= ARC_FUNCTION_ILINK2; ++ else if (!strcmp (TREE_STRING_POINTER (value), "firq")) ++ fn_type |= ARC_FUNCTION_FIRQ; ++ else ++ gcc_unreachable (); + } + + return fun->machine->fn_type = fn_type; +@@ -2458,7 +2501,7 @@ arc_compute_function_type (struct function *fun) + static bool + arc_must_save_register (int regno, struct function *func) + { +- enum arc_function_type fn_type = arc_compute_function_type (func); ++ unsigned int fn_type = arc_compute_function_type (func); + bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno) + && ARC_AUTO_IRQ_P (fn_type)); + bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type); +@@ -2968,7 +3011,11 @@ arc_expand_prologue (void) + Change the stack layout so that we rather store a high register with the + PRE_MODIFY, thus enabling more short insn generation.) */ + int first_offset = 0; +- enum arc_function_type fn_type = arc_compute_function_type (cfun); ++ unsigned int fn_type = arc_compute_function_type (cfun); ++ ++ /* Naked functions don't have prologue. */ ++ if (ARC_NAKED_P (fn_type)) ++ return; + + /* Compute total frame size. */ + size = arc_compute_frame_size (); +@@ -3068,10 +3115,7 @@ void + arc_expand_epilogue (int sibcall_p) + { + int size; +- enum arc_function_type fn_type = arc_compute_function_type (cfun); +- +- size = arc_compute_frame_size (); +- ++ unsigned int fn_type = arc_compute_function_type (cfun); + unsigned int pretend_size = cfun->machine->frame_info.pretend_size; + unsigned int frame_size; + unsigned int size_to_deallocate; +@@ -3081,6 +3125,16 @@ arc_expand_epilogue (int sibcall_p) + int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0; + rtx insn; + ++ /* Naked functions don't have epilogue. */ ++ if (ARC_NAKED_P (fn_type)) ++ { ++ if (sibcall_p == FALSE) ++ emit_jump_insn (gen_simple_return ()); ++ return; ++ } ++ ++ size = arc_compute_frame_size (); ++ + size_to_deallocate = size; + + frame_size = size - (pretend_size + +@@ -9820,37 +9874,60 @@ arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee) + return true; + } + +-int arc_return_address_regs[5] = +- {0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM, ILINK1_REGNUM}; ++/* Return the register number of the register holding the return address ++ for a function of type TYPE. */ ++ ++int ++arc_return_address_register (unsigned int fn_type) ++{ ++ int regno = 0; ++ ++ if (ARC_INTERRUPT_P (fn_type)) ++ { ++ if (((fn_type & ARC_FUNCTION_ILINK1) | ARC_FUNCTION_FIRQ) != 0) ++ regno = ILINK1_REGNUM; ++ else if ((fn_type & ARC_FUNCTION_ILINK2) != 0) ++ regno = ILINK2_REGNUM; ++ else ++ gcc_unreachable (); ++ } ++ else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type)) ++ regno = RETURN_ADDR_REGNUM; + +-/* Implement EPILOGUE__USES. ++ gcc_assert (regno != 0); ++ return regno; ++} ++ ++/* Implement EPILOGUE_USES. + Return true if REGNO should be added to the deemed uses of the epilogue. + +- We use the return address +- arc_return_address_regs[arc_compute_function_type (cfun)]. But +- also, we have to make sure all the register restore instructions +- are known to be live in interrupt functions, plus the blink +- register if it is clobbered by the isr. */ ++ We have to make sure all the register restore instructions are ++ known to be live in interrupt functions, plus the blink register if ++ it is clobbered by the isr. */ + + bool + arc_epilogue_uses (int regno) + { ++ unsigned int fn_type; ++ + if (regno == arc_tp_regno) + return true; ++ ++ fn_type = arc_compute_function_type (cfun); + if (reload_completed) + { + if (ARC_INTERRUPT_P (cfun->machine->fn_type)) + { + if (!fixed_regs[regno]) + return true; +- return ((regno == arc_return_address_regs[cfun->machine->fn_type]) ++ return ((regno == arc_return_address_register (fn_type)) + || (regno == RETURN_ADDR_REGNUM)); + } + else + return regno == RETURN_ADDR_REGNUM; + } + else +- return regno == arc_return_address_regs[arc_compute_function_type (cfun)]; ++ return regno == arc_return_address_register (fn_type); + } + + /* Helper for EH_USES macro. */ +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 1f0f4989c239..9fedac285010 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1334,10 +1334,6 @@ do { \ + #define ASM_OUTPUT_ALIGNED_DECL_LOCAL(STREAM, DECL, NAME, SIZE, ALIGNMENT) \ + arc_asm_output_aligned_decl_local (STREAM, DECL, NAME, SIZE, ALIGNMENT, 0) + +-/* To translate the return value of arc_function_type into a register number +- to jump through for function return. */ +-extern int arc_return_address_regs[5]; +- + /* Debugging information. */ + + /* Generate DBX and DWARF debugging information. */ +@@ -1473,22 +1469,38 @@ extern struct rtx_def *arc_compare_op0, *arc_compare_op1; + + /* ARC function types. */ + enum arc_function_type { +- ARC_FUNCTION_UNKNOWN, ARC_FUNCTION_NORMAL, ++ /* No function should have the unknown type. This value is used to ++ indicate the that function type has not yet been computed. */ ++ ARC_FUNCTION_UNKNOWN = 0, ++ ++ /* The normal function type indicates that the function has the ++ standard prologue and epilogue. */ ++ ARC_FUNCTION_NORMAL = 1 << 0, + /* These are interrupt handlers. The name corresponds to the register + name that contains the return address. */ +- ARC_FUNCTION_ILINK1, ARC_FUNCTION_ILINK2, ++ ARC_FUNCTION_ILINK1 = 1 << 1, ++ ARC_FUNCTION_ILINK2 = 1 << 2, + /* Fast interrupt is only available on ARCv2 processors. */ +- ARC_FUNCTION_FIRQ ++ ARC_FUNCTION_FIRQ = 1 << 3, ++ /* The naked function type indicates that the function does not have ++ prologue or epilogue, and that no stack frame is available. */ ++ ARC_FUNCTION_NAKED = 1 << 4 + }; +-#define ARC_INTERRUPT_P(TYPE) \ +- (((TYPE) == ARC_FUNCTION_ILINK1) || ((TYPE) == ARC_FUNCTION_ILINK2) \ +- || ((TYPE) == ARC_FUNCTION_FIRQ)) + +-#define ARC_FAST_INTERRUPT_P(TYPE) ((TYPE) == ARC_FUNCTION_FIRQ) ++/* Check if a function is an interrupt function. */ ++#define ARC_INTERRUPT_P(TYPE) \ ++ (((TYPE) & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_ILINK2 \ ++ | ARC_FUNCTION_FIRQ)) != 0) ++ ++/* Check if a function is a fast interrupt function. */ ++#define ARC_FAST_INTERRUPT_P(TYPE) (((TYPE) & ARC_FUNCTION_FIRQ) != 0) ++ ++/* Check if a function is normal, that is, has standard prologue and ++ epilogue. */ ++#define ARC_NORMAL_P(TYPE) (((TYPE) & ARC_FUNCTION_NORMAL) != 0) + +-/* Compute the type of a function from its DECL. Needed for EPILOGUE_USES. */ +-struct function; +-extern enum arc_function_type arc_compute_function_type (struct function *); ++/* Check if a function is naked. */ ++#define ARC_NAKED_P(TYPE) (((TYPE) & ARC_FUNCTION_NAKED) != 0) + + /* Called by crtstuff.c to make calls to function FUNCTION that are defined in + SECTION_OP, and then to switch back to text section. */ +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index c2bcfb530ad7..2c5e5f4a4c1d 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -503,8 +503,8 @@ + (cond [(eq_attr "in_delay_slot" "false") + (const_string "no") + (match_test "regno_clobbered_p +- (arc_return_address_regs +- [arc_compute_function_type (cfun)], ++ (arc_return_address_register ++ (arc_compute_function_type (cfun)), + insn, SImode, 1)") + (const_string "no")] + (const_string "yes"))) +@@ -4774,7 +4774,8 @@ + { + rtx reg + = gen_rtx_REG (Pmode, +- arc_return_address_regs[arc_compute_function_type (cfun)]); ++ arc_return_address_register (arc_compute_function_type ++ (cfun))); + + if (TARGET_V2 + && ARC_INTERRUPT_P (arc_compute_function_type (cfun))) +@@ -4823,7 +4824,8 @@ + xop[0] = operands[0]; + xop[1] + = gen_rtx_REG (Pmode, +- arc_return_address_regs[arc_compute_function_type (cfun)]); ++ arc_return_address_register (arc_compute_function_type ++ (cfun))); + + if (TARGET_PAD_RETURN) + arc_pad_return (); +diff --git a/gcc/testsuite/gcc.target/arc/naked-1.c b/gcc/testsuite/gcc.target/arc/naked-1.c +new file mode 100644 +index 000000000000..e8e4f7cd3152 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/naked-1.c +@@ -0,0 +1,18 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O0" } */ ++/* Check that naked functions don't place arguments on the stack at ++ optimisation level '-O0'. */ ++extern void bar (int); ++ ++void __attribute__((naked)) ++foo (int n, int m) ++{ ++ bar (n + m); ++} ++/* { dg-final { scan-assembler "\tbl @bar" } } */ ++/* { dg-final { scan-assembler "\tj.* \\\[blink\\\]" } } */ ++ ++/* Look for things that would appear in a non-naked function, but which ++ should not appear in a naked function. */ ++/* { dg-final { scan-assembler-not "\tst.* " } } */ ++/* { dg-final { scan-assembler-not "\tmov fp,sp" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/naked-2.c b/gcc/testsuite/gcc.target/arc/naked-2.c +new file mode 100644 +index 000000000000..7ada2cea6390 +--- /dev/null ++++ b/gcc/testsuite/gcc.target/arc/naked-2.c +@@ -0,0 +1,26 @@ ++/* { dg-do compile } */ ++/* { dg-options "-O0" } */ ++/* Check that naked functions don't place arguments on the stack at ++ optimisation level '-O0'. */ ++ ++#if defined(__HS__) || defined(__EM__) ++# define ILINK "ilink" ++#else ++# define ILINK "ilink1" ++#endif ++ ++extern void bar (int); ++ ++void __attribute__((naked, interrupt(ILINK))) ++foo (int n, int m) ++{ ++ bar (n + m); ++} ++/* { dg-final { scan-assembler "\tbl @bar" } } */ ++/* { dg-final { scan-assembler "\trtie" { xfail { arc700 || arc6xx } } } } */ ++/* { dg-final { scan-assembler "j.*\[ilink1\]" { xfail { archs || arcem } } } } */ ++ ++/* Look for things that would appear in a non-naked function, but which ++ should not appear in a naked function. */ ++/* { dg-final { scan-assembler-not "\tst.* " } } */ ++/* { dg-final { scan-assembler-not "\tmov fp,sp" } } */ +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0080-ARC-Correct-and-update-ARC-builtin-documentation.patch b/toolchain/gcc/patches/6.3.0/0080-ARC-Correct-and-update-ARC-builtin-documentation.patch new file mode 100644 index 0000000..cd59369 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0080-ARC-Correct-and-update-ARC-builtin-documentation.patch @@ -0,0 +1,204 @@ +From 0b51f18bb0fa0e952fe2add82babb39457a29d47 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 14 Dec 2016 12:33:15 +0100 +Subject: [PATCH 80/89] [ARC] Correct and update ARC builtin documentation. + +gcc/ +2016-12-14 Claudiu Zissulescu + + * doc/extend.texi (ARC Built-in Functions): Correct and update ARC + builtin documentation. +--- + gcc/doc/extend.texi | 128 ++++++++++++++++++++++++++++++++++++++++++++++------ + 1 file changed, 113 insertions(+), 15 deletions(-) + +diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi +index ee2715d7ea62..be6c66d0b739 100644 +--- a/gcc/doc/extend.texi ++++ b/gcc/doc/extend.texi +@@ -11683,6 +11683,13 @@ brk + @end example + @end deftypefn + ++@deftypefn {Built-in Function} void __builtin_arc_clri (unsigned int @var{c}) ++Only valid for ARCv2 architecture. Generates ++@example ++clri @var{c} ++@end example ++@end deftypefn ++ + @deftypefn {Built-in Function} {unsigned int} __builtin_arc_core_read (unsigned int @var{regno}) + The operand is the number of a register to be read. Generates: + @example +@@ -11711,6 +11718,15 @@ where the value in @var{dest} will be the result returned from the + built-in. + @end deftypefn + ++@deftypefn {Built-in Function} int __builtin_arc_ffs (int @var{a}) ++Only valid for ARCv2 cpu cores and @option{-mnorm}. Generates: ++@example ++ffs @var{dest}, @var{a} ++@end example ++Where the value in @var{dest} will be the result returned from the ++built-in. ++@end deftypefn ++ + @deftypefn {Built-in Function} void __builtin_arc_flag (unsigned int @var{a}) + Generates + @example +@@ -11718,28 +11734,30 @@ flag @var{a} + @end example + @end deftypefn + +-@deftypefn {Built-in Function} {unsigned int} __builtin_arc_lr (unsigned int @var{auxr}) +-The operand, @var{auxv}, is the address of an auxiliary register and +-must be a compile time constant. Generates: ++@deftypefn {Built-in Function} int __builtin_arc_fls (int @var{a}) ++Only valid for ARCv2 cpu cores and @option{-mnorm}. Generates: + @example +-lr @var{dest}, [@var{auxr}] ++fls @var{dest}, @var{a} + @end example + Where the value in @var{dest} will be the result returned from the + built-in. + @end deftypefn + +-@deftypefn {Built-in Function} void __builtin_arc_mul64 (int @var{a}, int @var{b}) +-Only available with @option{-mmul64}. Generates: ++@deftypefn {Built-in Function} void __builtin_arc_kflag (unsigned int @var{cc}) ++Only valid for ARCv2 architecture. Generates: + @example +-mul64 @var{a}, @var{b} ++kflag @var{cc} + @end example + @end deftypefn + +-@deftypefn {Built-in Function} void __builtin_arc_mulu64 (unsigned int @var{a}, unsigned int @var{b}) +-Only available with @option{-mmul64}. Generates: ++@deftypefn {Built-in Function} {unsigned int} __builtin_arc_lr (unsigned int @var{auxr}) ++The operand, @var{auxv}, is the address of an auxiliary register and ++must be a compile time constant. Generates: + @example +-mulu64 @var{a}, @var{b} ++lr @var{dest}, [@var{auxr}] + @end example ++Where the value in @var{dest} will be the result returned from the ++built-in. + @end deftypefn + + @deftypefn {Built-in Function} void __builtin_arc_nop (void) +@@ -11778,6 +11796,13 @@ rtie + @end example + @end deftypefn + ++@deftypefn {Built-in Function} void __builtin_arc_seti (int @var{c}) ++Only valid for ARCv2 cpu cores. Generates: ++@example ++seti @var{c} ++@end example ++@end deftypefn ++ + @deftypefn {Built-in Function} void __builtin_arc_sleep (int @var{a} + Generates: + @example +@@ -11785,12 +11810,12 @@ sleep @var{a} + @end example + @end deftypefn + +-@deftypefn {Built-in Function} void __builtin_arc_sr (unsigned int @var{auxr}, unsigned int @var{val}) +-The first argument, @var{auxv}, is the address of an auxiliary +-register, the second argument, @var{val}, is a compile time constant +-to be written to the register. Generates: ++@deftypefn {Built-in Function} void __builtin_arc_sr (unsigned int @var{val}, unsigned int @var{auxr}) ++Store the 32-bit word held in source operand 1 (@var{val}) into the ++auxiliary register whose address is obtained from the source operand 2 ++(@var{auxr}). Generates: + @example +-sr @var{auxr}, [@var{val}] ++sr @var{val}, [@var{auxr}] + @end example + @end deftypefn + +@@ -12072,6 +12097,79 @@ void __builtin_arc_vst16_n (__v8hi, const int, const int, const int) + void __builtin_arc_vst32_n (__v8hi, const int, const int, const int) + @end example + ++@subsection ARCv2 SIMD Built-in Functions ++ ++SIMD builtins provided by the compiler can be used to generate the ++vector instructions. This section describes the available builtins ++and their usage in programs. With the @option{-mmpy-option} option ++with values from 7 to 9, the compiler provides 32-bit or 64-bit vector ++types, which can be specified using the @code{vector_size} ++attribute. For example: ++@example ++typedef int __v2hi __attribute__((vector_size(4))); ++typedef short __v4hi __attribute__((vector_size(8))); ++typedef short __v2si __attribute__((vector_size(8))); ++@end example ++ ++The following take two @code{__v4hi} arguments and return a long long ++int. These builtins are available only for @option{-mpy-option=9}. ++@example ++long long __builtin_arc_qmach (__v4hi, __v4hi); ++long long __builtin_arc_qmachu (__v4hi, __v4hi); ++long long __builtin_arc_qmpyh (__v4hi, __v4hi); ++long long __builtin_arc_qmpyhu (__v4hi, __v4hi); ++@end example ++ ++The following take two @code{__v2hi} arguments and return an ++int. These builtins are available only for @option{-mpy-option=7} or ++higher. ++@example ++int __builtin_arc_dmach (__v2hi, __v2hi); ++int __builtin_arc_dmachu (__v2hi, __v2hi); ++int __builtin_arc_dmpyh (__v2hi, __v2hi); ++int __builtin_arc_dmpyhu (__v2hi, __v2hi); ++@end example ++ ++The following take a @code{__v2hi} argument, a @code{__v2si} argument ++and return a long long int. These builtins are available only for ++@option{-mpy-option=9}. ++@example ++long long __builtin_arc_dmacwh (__v2si, __v2hi); ++long long __builtin_arc_dmacwhu (__v2si, __v2hi); ++@end example ++ ++The following take two @code{__v2hi} arguments and return a ++@code{__v2si}. These builtins are available only for @option{-mpy-option=8} or ++higher. ++@example ++__v2si __builtin_arc_vmac2h (__v2hi, __v2hi); ++__v2si __builtin_arc_vmac2hu (__v2hi, __v2hi); ++__v2si __builtin_arc_vmpy2h (__v2hi, __v2hi); ++__v2si __builtin_arc_vmpy2hu (__v2hi, __v2hi); ++@end example ++ ++The following take two @code{__v2hi} arguments and return a ++@code{__v2hi}. These builtins are available only for @option{-mpy-option=7} or ++higher. ++@example ++__v2hi __builtin_arc_addsubv2hi3 (__v2hi, __v2hi); ++__v2hi __builtin_arc_subaddv2hi3 (__v2hi, __v2hi); ++@end example ++ ++The following take two @code{__v2si} arguments and return a ++@code{__v2si}. These builtins are available only for @option{-mpy-option=9}. ++@example ++__v2si __builtin_arc_addsubv2si3 (__v2si, __v2si); ++__v2si __builtin_arc_subaddv2si3 (__v2si, __v2si); ++@end example ++ ++The following take two @code{__v4hi} arguments and return a ++@code{__v4hi}. These builtins are available only for @option{-mpy-option=9}. ++@example ++__v4hi __builtin_arc_addsubv4hi3 (__v4hi, __v4hi); ++__v4hi __builtin_arc_subaddv4hi3 (__v4hi, __v4hi); ++@end example ++ + @node ARM iWMMXt Built-in Functions + @subsection ARM iWMMXt Built-in Functions + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0081-ARC-Change-predicate-movv2hi-to-avoid-scaled-address.patch b/toolchain/gcc/patches/6.3.0/0081-ARC-Change-predicate-movv2hi-to-avoid-scaled-address.patch new file mode 100644 index 0000000..800f2ff --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0081-ARC-Change-predicate-movv2hi-to-avoid-scaled-address.patch @@ -0,0 +1,30 @@ +From ffd583d0b3bb5d6feb92541820aa73abaf188ed8 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Sat, 17 Dec 2016 13:57:05 -0500 +Subject: [PATCH 81/89] [ARC] Change predicate movv2hi to avoid scaled + addresses. + +2016-12-17 Claudiu Zissulescu + + * config/arc/simdext.md (movv2hi_insn): Change predicate to avoid + scaled addresses. +--- + gcc/config/arc/simdext.md | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/simdext.md b/gcc/config/arc/simdext.md +index 95e9d2c038ff..f8285a1156a2 100644 +--- a/gcc/config/arc/simdext.md ++++ b/gcc/config/arc/simdext.md +@@ -1320,7 +1320,7 @@ + }") + + (define_insn_and_split "*movv2hi_insn" +- [(set (match_operand:V2HI 0 "nonimmediate_operand" "=r,r,r,m") ++ [(set (match_operand:V2HI 0 "move_dest_operand" "=r,r,r,m") + (match_operand:V2HI 1 "general_operand" "i,r,m,r"))] + "(register_operand (operands[0], V2HImode) + || register_operand (operands[1], V2HImode))" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0082-ARC-Update-non-commutative_binary_comparison-pattern.patch b/toolchain/gcc/patches/6.3.0/0082-ARC-Update-non-commutative_binary_comparison-pattern.patch new file mode 100644 index 0000000..d12d8eb --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0082-ARC-Update-non-commutative_binary_comparison-pattern.patch @@ -0,0 +1,63 @@ +From 9e505f78b4f50d6a5b89c2271073ca956a18f3dc Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 20 Dec 2016 10:59:21 +0100 +Subject: [PATCH 82/89] [ARC] Update (non)commutative_binary_comparison + patterns. + +gcc/ +2016-12-20 Claudiu Zissulescu + + * config/arc/arc.md (commutative_binary_comparison): Remove 'I' + constraint. It is not valid for the pattern. + (noncommutative_binary_comparison): Likewise. +--- + gcc/config/arc/arc.md | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 2c5e5f4a4c1d..16f71b383b25 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -947,15 +947,15 @@ + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator:CC_ZN 5 "zn_compare_operator" + [(match_operator:SI 4 "commutative_operator" +- [(match_operand:SI 1 "register_operand" "%c,c,c") +- (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")]) ++ [(match_operand:SI 1 "register_operand" "%c,c") ++ (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) + (const_int 0)])) +- (clobber (match_scratch:SI 3 "=X,1,X"))] ++ (clobber (match_scratch:SI 3 "=X,X"))] + "" + "%O4.f 0,%1,%2" + [(set_attr "type" "compare") + (set_attr "cond" "set_zn") +- (set_attr "length" "4,4,8")]) ++ (set_attr "length" "4,8")]) + + ; for flag setting 'add' instructions like if (a+b) { ...} + ; the combiner needs this pattern +@@ -1049,15 +1049,15 @@ + [(set (match_operand:CC_ZN 0 "cc_set_register" "") + (match_operator:CC_ZN 5 "zn_compare_operator" + [(match_operator:SI 4 "noncommutative_operator" +- [(match_operand:SI 1 "register_operand" "c,c,c") +- (match_operand:SI 2 "nonmemory_operand" "cL,I,?Cal")]) ++ [(match_operand:SI 1 "register_operand" "c,c") ++ (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) + (const_int 0)])) +- (clobber (match_scratch:SI 3 "=X,1,X"))] ++ (clobber (match_scratch:SI 3 "=X,X"))] + "TARGET_BARREL_SHIFTER || GET_CODE (operands[4]) == MINUS" + "%O4.f 0,%1,%2" + [(set_attr "type" "compare") + (set_attr "cond" "set_zn") +- (set_attr "length" "4,4,8")]) ++ (set_attr "length" "4,8")]) + + (define_expand "bic_f_zn" + [(parallel +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0083-ARC-Prevent-moving-stores-to-the-frame-before-the-st.patch b/toolchain/gcc/patches/6.3.0/0083-ARC-Prevent-moving-stores-to-the-frame-before-the-st.patch new file mode 100644 index 0000000..74b0d8a --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0083-ARC-Prevent-moving-stores-to-the-frame-before-the-st.patch @@ -0,0 +1,86 @@ +From cbd8e54244cd02bdcf4f1057be3ce96631f35ac3 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 3 Jan 2017 12:06:28 -0500 +Subject: [PATCH 83/89] [ARC] Prevent moving stores to the frame before the + stack adjustment. + +If the stack pointer is needed, emit a special barrier that will prevent +the scheduler from moving stores to the frame before the stack adjustment. + +2017-01-03 Claudiu Zissulescu + + * config/arc/arc.c (arc_expand_prologue): Emit a special barrier + to prevent store reordering. + * config/arc/arc.md (UNSPEC_ARC_STKTIE): Define. + (type): Add block type. + (stack_tie): Define special instruction to be used in + expand_prologue. +--- + gcc/config/arc/arc.c | 10 +++++++++- + gcc/config/arc/arc.md | 15 ++++++++++++++- + 2 files changed, 23 insertions(+), 2 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 6f21fc372516..110556c0601d 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -3101,7 +3101,15 @@ arc_expand_prologue (void) + frame_size_to_allocate -= first_offset; + /* Allocate the stack frame. */ + if (frame_size_to_allocate > 0) +- frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate); ++ { ++ frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate); ++ /* If the frame pointer is needed, emit a special barrier that ++ will prevent the scheduler from moving stores to the frame ++ before the stack adjustment. */ ++ if (arc_frame_pointer_needed ()) ++ emit_insn (gen_stack_tie (stack_pointer_rtx, ++ hard_frame_pointer_rtx)); ++ } + + /* Setup the gp register, if needed. */ + if (crtl->uses_pic_offset_table) +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 16f71b383b25..448157cf2b65 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -135,6 +135,7 @@ + UNSPEC_ARC_VMAC2HU + UNSPEC_ARC_VMPY2H + UNSPEC_ARC_VMPY2HU ++ UNSPEC_ARC_STKTIE + ]) + + (define_c_enum "vunspec" [ +@@ -204,7 +205,7 @@ + simd_vcompare, simd_vpermute, simd_vpack, simd_vpack_with_acc, + simd_valign, simd_valign_with_acc, simd_vcontrol, + simd_vspecial_3cycle, simd_vspecial_4cycle, simd_dma, mul16_em, div_rem, +- fpu" ++ fpu, block" + (cond [(eq_attr "is_sfunc" "yes") + (cond [(match_test "!TARGET_LONG_CALLS_SET && (!TARGET_MEDIUM_CALLS || GET_CODE (PATTERN (insn)) != COND_EXEC)") (const_string "call") + (match_test "flag_pic") (const_string "sfunc")] +@@ -6480,6 +6481,18 @@ + (set_attr "predicable" "yes,no,no,yes,no") + (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")]) + ++(define_insn "stack_tie" ++ [(set (mem:BLK (scratch)) ++ (unspec:BLK [(match_operand:SI 0 "register_operand" "rb") ++ (match_operand:SI 1 "register_operand" "rb")] ++ UNSPEC_ARC_STKTIE))] ++ "" ++ "" ++ [(set_attr "length" "0") ++ (set_attr "iscompact" "false") ++ (set_attr "type" "block")] ++ ) ++ + ;; include the arc-FPX instructions + (include "fpx.md") + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0084-ARC-LRA-Fix-tests-asm-constraints.patch b/toolchain/gcc/patches/6.3.0/0084-ARC-LRA-Fix-tests-asm-constraints.patch new file mode 100644 index 0000000..1821f1a --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0084-ARC-LRA-Fix-tests-asm-constraints.patch @@ -0,0 +1,46 @@ +From db51a1a82ab3fcf294fa25cf74a9c98778a1505f Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 9 Jan 2017 10:26:52 +0100 +Subject: [PATCH 84/89] [ARC] [LRA] Fix tests asm constraints. + +LRA doesn't like the 'X' constraint as used in our tests, remove it. + +gcc/testsuite +2017-01-09 Claudiu Zissulescu + + * gcc.target/arc/mulsi3_highpart-1.c: Remove 'X' constraint. + * gcc.target/arc/mulsi3_highpart-2.c: Likewise. +--- + gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c | 2 +- + gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c +index 57cb95b91fc1..5fd6c3603633 100644 +--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c ++++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c +@@ -7,7 +7,7 @@ + static int + id (int i) + { +- asm ("": "+Xr" (i)); ++ asm ("": "+r" (i)); + return i; + } + +diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c +index 287d96d4ee9a..6ec4bc5d8755 100644 +--- a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c ++++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c +@@ -9,7 +9,7 @@ + static int + id (int i) + { +- asm ("": "+Xr" (i)); ++ asm ("": "+r" (i)); + return i; + } + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0085-ARC-Test-against-frame_pointer_needed-in-arc_can_eli.patch b/toolchain/gcc/patches/6.3.0/0085-ARC-Test-against-frame_pointer_needed-in-arc_can_eli.patch new file mode 100644 index 0000000..b064139 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0085-ARC-Test-against-frame_pointer_needed-in-arc_can_eli.patch @@ -0,0 +1,35 @@ +From 6747353bf09391477820fcbb17b224b70b6d7a81 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 9 Jan 2017 12:42:41 +0100 +Subject: [PATCH 85/89] [ARC] Test against frame_pointer_needed in + arc_can_eliminate. + +arc_can_eliminate is using arc_frmae_pointer_required() which is wrong +as the frame_pointer_needed can be set on different conditions. Fix it +by calling arc_frame_pointer_needed(). + +gcc/ +2017-01-09 Claudiu Zissulescu + + * config/arc/arc.c (arc_can_eliminate): Test against + arc_frame_pointer_needed. +--- + gcc/config/arc/arc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index 110556c0601d..b49c54ffe470 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -4809,7 +4809,7 @@ arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED, + static bool + arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) + { +- return to == FRAME_POINTER_REGNUM || !arc_frame_pointer_required (); ++ return ((to == FRAME_POINTER_REGNUM) || !arc_frame_pointer_needed ()); + } + + /* Define the offset between two registers, one to be eliminated, and +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0086-ARC-Define-ADDITIONAL_REGISTER_NAMES.patch b/toolchain/gcc/patches/6.3.0/0086-ARC-Define-ADDITIONAL_REGISTER_NAMES.patch new file mode 100644 index 0000000..e5469f9 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0086-ARC-Define-ADDITIONAL_REGISTER_NAMES.patch @@ -0,0 +1,36 @@ +From 54f16230f5a74b7c2bb9015c480743b948a41192 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Mon, 9 Jan 2017 13:44:27 +0100 +Subject: [PATCH 86/89] [ARC] Define ADDITIONAL_REGISTER_NAMES. + +This macro is needed to be used with -ffixed- option, and inline asm. + +gcc/ +2017-01-09 Claudiu Zissulescu + + * config/arc/arc.h (ADDITIONAL_REGISTER_NAMES): Define. +--- + gcc/config/arc/arc.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h +index 9fedac285010..6eafef494d19 100644 +--- a/gcc/config/arc/arc.h ++++ b/gcc/config/arc/arc.h +@@ -1233,6 +1233,13 @@ extern char rname56[], rname57[], rname58[], rname59[]; + "lp_start", "lp_end" \ + } + ++#define ADDITIONAL_REGISTER_NAMES \ ++{ \ ++ {"ilink", 29}, \ ++ {"r29", 29}, \ ++ {"r30", 30} \ ++} ++ + /* Entry to the insn conditionalizer. */ + #define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \ + arc_final_prescan_insn (INSN, OPVEC, NOPERANDS) +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0087-ARC-LRA-Avoid-emitting-COND_EXEC-during-expand.patch b/toolchain/gcc/patches/6.3.0/0087-ARC-LRA-Avoid-emitting-COND_EXEC-during-expand.patch new file mode 100644 index 0000000..0a49ff0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0087-ARC-LRA-Avoid-emitting-COND_EXEC-during-expand.patch @@ -0,0 +1,101 @@ +From dba9cdbce9cdad24dc956134d93cb362b38b8f00 Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 10 Jan 2017 14:07:00 +0100 +Subject: [PATCH 87/89] [ARC] [LRA] Avoid emitting COND_EXEC during expand. + +Emmitting COND_EXEC rtxes during expand does not always work. + +gcc/ +2017-01-10 Claudiu Zissulescu + + * config/arc/arc.md (clzsi2): Expand to an arc_clzsi2 instruction + that also clobbers the CC register. The old expand code is moved + to ... + (*arc_clzsi2): ... here. + (ctzsi2): Expand to an arc_ctzsi2 instruction that also clobbers + the CC register. The old expand code is moved to ... + (arc_ctzsi2): ... here. +--- + gcc/config/arc/arc.md | 41 ++++++++++++++++++++++++++++++++++------- + 1 file changed, 34 insertions(+), 7 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 448157cf2b65..65b1ca330590 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -4449,9 +4449,21 @@ + (set_attr "type" "two_cycle_core,two_cycle_core")]) + + (define_expand "clzsi2" +- [(set (match_operand:SI 0 "dest_reg_operand" "") +- (clz:SI (match_operand:SI 1 "register_operand" "")))] ++ [(parallel ++ [(set (match_operand:SI 0 "register_operand" "") ++ (clz:SI (match_operand:SI 1 "register_operand" ""))) ++ (clobber (match_dup 2))])] ++ "TARGET_NORM" ++ "operands[2] = gen_rtx_REG (CC_ZNmode, CC_REG);") ++ ++(define_insn_and_split "*arc_clzsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (clz:SI (match_operand:SI 1 "register_operand" "r"))) ++ (clobber (reg:CC_ZN CC_REG))] + "TARGET_NORM" ++ "#" ++ "reload_completed" ++ [(const_int 0)] + { + emit_insn (gen_norm_f (operands[0], operands[1])); + emit_insn +@@ -4468,9 +4480,23 @@ + }) + + (define_expand "ctzsi2" +- [(set (match_operand:SI 0 "register_operand" "") +- (ctz:SI (match_operand:SI 1 "register_operand" "")))] ++ [(match_operand:SI 0 "register_operand" "") ++ (match_operand:SI 1 "register_operand" "")] + "TARGET_NORM" ++ " ++ emit_insn (gen_arc_ctzsi2 (operands[0], operands[1])); ++ DONE; ++") ++ ++(define_insn_and_split "arc_ctzsi2" ++ [(set (match_operand:SI 0 "register_operand" "=r") ++ (ctz:SI (match_operand:SI 1 "register_operand" "r"))) ++ (clobber (reg:CC_ZN CC_REG)) ++ (clobber (match_scratch:SI 2 "=&r"))] ++ "TARGET_NORM" ++ "#" ++ "reload_completed" ++ [(const_int 0)] + { + rtx temp = operands[0]; + +@@ -4478,10 +4504,10 @@ + || (REGNO (temp) < FIRST_PSEUDO_REGISTER + && !TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], + REGNO (temp)))) +- temp = gen_reg_rtx (SImode); ++ temp = operands[2]; + emit_insn (gen_addsi3 (temp, operands[1], constm1_rtx)); + emit_insn (gen_bic_f_zn (temp, temp, operands[1])); +- emit_insn (gen_clrsbsi2 (temp, temp)); ++ emit_insn (gen_clrsbsi2 (operands[0], temp)); + emit_insn + (gen_rtx_COND_EXEC + (VOIDmode, +@@ -4491,7 +4517,8 @@ + (gen_rtx_COND_EXEC + (VOIDmode, + gen_rtx_GE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG), const0_rtx), +- gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), temp)))); ++ gen_rtx_SET (operands[0], gen_rtx_MINUS (SImode, GEN_INT (31), ++ operands[0])))); + DONE; + }) + +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0088-ARC-Clean-up-building-warnings.patch b/toolchain/gcc/patches/6.3.0/0088-ARC-Clean-up-building-warnings.patch new file mode 100644 index 0000000..ffd57a0 --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0088-ARC-Clean-up-building-warnings.patch @@ -0,0 +1,154 @@ +From 1a845926781d6db1793a0ee6979781dcb0becdaa Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Tue, 10 Jan 2017 16:47:16 +0100 +Subject: [PATCH 88/89] [ARC] Clean up building warnings + +gcc/ +2017-01-10 Claudiu Zissulescu + + * config/arc/arc.md (movsi_set_cc_insn): Remove modes for operands + that are using special predicates. + (unary_comparison): Likewise. + (tst_bitfield_tst): Likewise. + (tst_bitfield_asr): Likewise. + (tst_bitfield): Likewise. + (commutative_binary_comparison): Likewise. + (noncommutative_binary_comparison): Likewise. + (scc_insn): Likewise. + (neg_scc_insn): Likewise. + (not_scc_insn): Likewise. + * config/arc/predicates.md (proper_comparison_operator): Make it + special. + (equality_comparison_operator): Likewise. +--- + gcc/config/arc/arc.md | 28 ++++++++++++++-------------- + gcc/config/arc/predicates.md | 4 ++-- + 2 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md +index 65b1ca330590..863c91b21975 100644 +--- a/gcc/config/arc/arc.md ++++ b/gcc/config/arc/arc.md +@@ -782,8 +782,8 @@ + [(set_attr "type" "store")]) + + (define_insn_and_split "*movsi_set_cc_insn" +- [(set (match_operand:CC_ZN 2 "cc_set_register" "") +- (match_operator:CC_ZN 3 "zn_compare_operator" ++ [(set (match_operand 2 "cc_set_register" "") ++ (match_operator 3 "zn_compare_operator" + [(match_operand:SI 1 "nonmemory_operand" "cI,cL,Cal") (const_int 0)])) + (set (match_operand:SI 0 "register_operand" "=w,w,w") + (match_dup 1))] +@@ -799,8 +799,8 @@ + (set_attr "length" "4,4,8")]) + + (define_insn "unary_comparison" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") +- (match_operator:CC_ZN 3 "zn_compare_operator" ++ [(set (match_operand 0 "cc_set_register" "") ++ (match_operator 3 "zn_compare_operator" + [(match_operator:SI 2 "unary_operator" + [(match_operand:SI 1 "register_operand" "c")]) + (const_int 0)]))] +@@ -891,7 +891,7 @@ + ; so we rather use an extra pattern for tst; + ; since this is about constants, reload shouldn't care. + (define_insn "*tst_bitfield_tst" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ [(set (match_operand 0 "cc_set_register" "") + (match_operator 4 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "c") +@@ -909,7 +909,7 @@ + + ; Likewise for asr.f. + (define_insn "*tst_bitfield_asr" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ [(set (match_operand 0 "cc_set_register" "") + (match_operator 4 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "c") +@@ -924,7 +924,7 @@ + (set_attr "length" "4")]) + + (define_insn "*tst_bitfield" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") ++ [(set (match_operand 0 "cc_set_register" "") + (match_operator 5 "zn_compare_operator" + [(zero_extract:SI + (match_operand:SI 1 "register_operand" "%Rcqq,c, c,Rrq,c") +@@ -945,8 +945,8 @@ + (set_attr "length" "*,4,4,4,8")]) + + (define_insn "*commutative_binary_comparison" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") +- (match_operator:CC_ZN 5 "zn_compare_operator" ++ [(set (match_operand 0 "cc_set_register" "") ++ (match_operator 5 "zn_compare_operator" + [(match_operator:SI 4 "commutative_operator" + [(match_operand:SI 1 "register_operand" "%c,c") + (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) +@@ -1047,8 +1047,8 @@ + (set_attr "length" "4,4,8")]) + + (define_insn "*noncommutative_binary_comparison" +- [(set (match_operand:CC_ZN 0 "cc_set_register" "") +- (match_operator:CC_ZN 5 "zn_compare_operator" ++ [(set (match_operand 0 "cc_set_register" "") ++ (match_operator 5 "zn_compare_operator" + [(match_operator:SI 4 "noncommutative_operator" + [(match_operand:SI 1 "register_operand" "c,c") + (match_operand:SI 2 "nonmemory_operand" "cL,Cal")]) +@@ -3641,7 +3641,7 @@ + + (define_insn_and_split "*scc_insn" + [(set (match_operand:SI 0 "dest_reg_operand" "=w") +- (match_operator:SI 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))] ++ (match_operator 1 "proper_comparison_operator" [(reg CC_REG) (const_int 0)]))] + "" + "#" + "reload_completed" +@@ -3664,7 +3664,7 @@ + ;; ??? Look up negscc insn. See pa.md for example. + (define_insn "*neg_scc_insn" + [(set (match_operand:SI 0 "dest_reg_operand" "=w") +- (neg:SI (match_operator:SI 1 "proper_comparison_operator" ++ (neg:SI (match_operator 1 "proper_comparison_operator" + [(reg CC_REG) (const_int 0)])))] + "" + "mov %0,-1\;sub.%D1 %0,%0,%0" +@@ -3673,7 +3673,7 @@ + + (define_insn "*not_scc_insn" + [(set (match_operand:SI 0 "dest_reg_operand" "=w") +- (not:SI (match_operator:SI 1 "proper_comparison_operator" ++ (not:SI (match_operator 1 "proper_comparison_operator" + [(reg CC_REG) (const_int 0)])))] + "" + "mov %0,1\;sub.%d1 %0,%0,%0" +diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md +index a6b81a147897..56e54784a374 100644 +--- a/gcc/config/arc/predicates.md ++++ b/gcc/config/arc/predicates.md +@@ -415,7 +415,7 @@ + ;; Return 1 if OP is a comparison operator valid for the mode of CC. + ;; This allows the use of MATCH_OPERATOR to recognize all the branch insns. + +-(define_predicate "proper_comparison_operator" ++(define_special_predicate "proper_comparison_operator" + (match_code "eq, ne, le, lt, ge, gt, leu, ltu, geu, gtu, unordered, ordered, uneq, unge, ungt, unle, unlt, ltgt") + { + enum rtx_code code = GET_CODE (op); +@@ -466,7 +466,7 @@ + } + }) + +-(define_predicate "equality_comparison_operator" ++(define_special_predicate "equality_comparison_operator" + (match_code "eq, ne")) + + (define_predicate "brcc_nolimm_operator" +-- +2.7.4 + diff --git a/toolchain/gcc/patches/6.3.0/0089-ARC-FIX-Attribute-naked-do-not-emit-return-instructi.patch b/toolchain/gcc/patches/6.3.0/0089-ARC-FIX-Attribute-naked-do-not-emit-return-instructi.patch new file mode 100644 index 0000000..aecc34f --- /dev/null +++ b/toolchain/gcc/patches/6.3.0/0089-ARC-FIX-Attribute-naked-do-not-emit-return-instructi.patch @@ -0,0 +1,64 @@ +From e18f1496a2f405188c3a0ab64bc593a7e0c422ab Mon Sep 17 00:00:00 2001 +From: Claudiu Zissulescu +Date: Wed, 11 Jan 2017 13:25:35 +0100 +Subject: [PATCH 89/89] [ARC][FIX] Attribute 'naked': do not emit return + instructions. + +--- + gcc/config/arc/arc.c | 6 +----- + gcc/testsuite/gcc.target/arc/naked-1.c | 2 +- + gcc/testsuite/gcc.target/arc/naked-2.c | 4 ++-- + 3 files changed, 4 insertions(+), 8 deletions(-) + +diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c +index b49c54ffe470..135606708d28 100644 +--- a/gcc/config/arc/arc.c ++++ b/gcc/config/arc/arc.c +@@ -3135,11 +3135,7 @@ arc_expand_epilogue (int sibcall_p) + + /* Naked functions don't have epilogue. */ + if (ARC_NAKED_P (fn_type)) +- { +- if (sibcall_p == FALSE) +- emit_jump_insn (gen_simple_return ()); +- return; +- } ++ return; + + size = arc_compute_frame_size (); + +diff --git a/gcc/testsuite/gcc.target/arc/naked-1.c b/gcc/testsuite/gcc.target/arc/naked-1.c +index e8e4f7cd3152..e45f433f73cd 100644 +--- a/gcc/testsuite/gcc.target/arc/naked-1.c ++++ b/gcc/testsuite/gcc.target/arc/naked-1.c +@@ -10,9 +10,9 @@ foo (int n, int m) + bar (n + m); + } + /* { dg-final { scan-assembler "\tbl @bar" } } */ +-/* { dg-final { scan-assembler "\tj.* \\\[blink\\\]" } } */ + + /* Look for things that would appear in a non-naked function, but which + should not appear in a naked function. */ ++/* { dg-final { scan-assembler-not "\tj.* \\\[blink\\\]" } } */ + /* { dg-final { scan-assembler-not "\tst.* " } } */ + /* { dg-final { scan-assembler-not "\tmov fp,sp" } } */ +diff --git a/gcc/testsuite/gcc.target/arc/naked-2.c b/gcc/testsuite/gcc.target/arc/naked-2.c +index 7ada2cea6390..7b7262f79167 100644 +--- a/gcc/testsuite/gcc.target/arc/naked-2.c ++++ b/gcc/testsuite/gcc.target/arc/naked-2.c +@@ -17,10 +17,10 @@ foo (int n, int m) + bar (n + m); + } + /* { dg-final { scan-assembler "\tbl @bar" } } */ +-/* { dg-final { scan-assembler "\trtie" { xfail { arc700 || arc6xx } } } } */ +-/* { dg-final { scan-assembler "j.*\[ilink1\]" { xfail { archs || arcem } } } } */ + + /* Look for things that would appear in a non-naked function, but which + should not appear in a naked function. */ ++/* { dg-final { scan-assembler-not "\trtie" } } */ ++/* { dg-final { scan-assembler-not "j.*\[ilink1\]" } } */ + /* { dg-final { scan-assembler-not "\tst.* " } } */ + /* { dg-final { scan-assembler-not "\tmov fp,sp" } } */ +-- +2.7.4 +