From patchwork Tue Feb 6 03:48:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 1895505 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=Rnh4XCee; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4TTTlB0lTtz23gT for ; Tue, 6 Feb 2024 14:49:24 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 880C83858402 for ; Tue, 6 Feb 2024 03:49:22 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by sourceware.org (Postfix) with ESMTPS id 6D4AE3858D33 for ; Tue, 6 Feb 2024 03:48:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6D4AE3858D33 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 6D4AE3858D33 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::635 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707191338; cv=none; b=jjsEbbCppkFvU4dsAZqitWiMOADBEnZuY5bdH9vgWE+QK8hTywx52psq2LAKqqtepS2HqNpE9j+m5Zr0s9B9OE1HnweNYHNWkAQ9MGkF+uV1cm5RZui0KNdkN06joKeUjVBBQbROJovrGhb8qv60KhVGkNwaz76QGLF7D8czjZE= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1707191338; c=relaxed/simple; bh=iTSLTs9yaElPeAKOfnMt6xaO7nUXW5wYnveqPxe5Kbc=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=sq9yVNyl470luClfhQFg066cLJ519Iyoe4ypATgvzJWJdkoOkBaIUxURmc8IQeCbObTVCpFxvVRySElqccM8s0YxN88iB5z6bJACx3N4erMCaOcfTTomKuSc+mm3lUQ9ebNF8fOfKxuJV2R4K8jRfUG5SIqqSAFPPLX56oZNCO4= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1d74045c463so40533935ad.3 for ; Mon, 05 Feb 2024 19:48:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1707191331; x=1707796131; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=qioBSUfeNzwnh1RNiwxx/QUqLB9BsP0DWXiDg1KIGrY=; b=Rnh4XCeeDceoZ2nsYTlVQDED3Vj3QljsE44Tn7qdd8h9scWwgnr8BQZJivoX/Yo7Gq Jk7GixdR4UUrmNOOza0G0/Qhfm9xS93GKXpxDJCGteiTIVTAi7OtetKwGApsYw0kRoLA Srb0EkkbOTRbcMUpsOVZBbUv1TYrsP94VkkunB6WAwTpE6K4+Bg4yYCv0FuiR5XxV/MD H6UKgx3H4NgVfAvy3KYE/xebox81AmPVg+DIl93S0DZlGGao3Jn6VCTTAf30yP7EZmA/ Syndo5YctP8x2aPyhvy/NHE/8QT4Bs+usi1zvcQLC64lGcLG5cFJXpB+GJ1MaKLvNYay VOIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1707191331; x=1707796131; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=qioBSUfeNzwnh1RNiwxx/QUqLB9BsP0DWXiDg1KIGrY=; b=aZ+zwok52QwnqUUxEdqxfZ17GXiJIsOEJaiXA/bHxonDJc+0AUtdXsJKF0yioKiTNh OL1ulUHvsHoKAQWOmnzu/aqIzWG+rqa6oTs2TjC3jBW6julHf/V1DxVNNn3FnWbeVYjT 5+0pV0EAgJvl+5mL7FKK/0jYmaiAEOr7iYc+uWrlXyBRjsD2CqCuz5ADMXPL8JPydQOk BOKBSxks1oPibJJb3hnewiwKtFs6FHllyT0k9l+gdecg1UTSMnv3bvE0BsfbUlthleZz f2+AFBT5tf8ZJU4Xa47R0IUP4kuYTp2dUWPKQN4l+6h8nGDMZU+7YGm3dEzlkqt9EIoC U26A== X-Gm-Message-State: AOJu0YyhBwS9to1RvfP8O3WmKy3b/Yep9wXP5sm7SEgYuIPjV1TIoFpy DQ70DVRfdNjV9G8S3X6IsohH5d9XgSoassmfXhijM196BD9nVXNHquawouyq X-Google-Smtp-Source: AGHT+IFyBryiwaI8OzgtBXNyV4DkTzuJkhv9Ss9vGi0uWr+uoEHv+cgPHNiQvBBDlC46TyDyW1HJow== X-Received: by 2002:a17:903:2b0e:b0:1d8:ef8d:a7ec with SMTP id mc14-20020a1709032b0e00b001d8ef8da7ecmr703860plb.2.1707191330536; Mon, 05 Feb 2024 19:48:50 -0800 (PST) Received: from gnu-cfl-3.localdomain ([172.56.168.224]) by smtp.gmail.com with ESMTPSA id x8-20020a170902b40800b001d9b0a15bbfsm664938plr.262.2024.02.05.19.48.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 05 Feb 2024 19:48:49 -0800 (PST) Received: from gnu-cfl-3.. (localhost [IPv6:::1]) by gnu-cfl-3.localdomain (Postfix) with ESMTP id 6F1C57402B9; Mon, 5 Feb 2024 19:48:48 -0800 (PST) From: "H.J. Lu" To: gcc-patches@gcc.gnu.org Cc: hongtao.liu@intel.com Subject: [PATCH] x86: Update constraints for APX NDD instructions Date: Mon, 5 Feb 2024 19:48:48 -0800 Message-ID: <20240206034848.6668-1-hjl.tools@gmail.com> X-Mailer: git-send-email 2.43.0 MIME-Version: 1.0 X-Spam-Status: No, score=-3023.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org 1. The only supported TLS code sequence with ADD is addq foo@gottpoff(%rip),%reg Change je constraint to a memory operand in APX NDD ADD pattern with register source operand. 2. The instruction length of APX NDD instructions with immediate operand: op imm, mem, reg may exceed the size limit of 15 byes when non-default address space, segment register or address size prefix are used. Add jM constraint which is a memory operand valid for APX NDD instructions with immediate operand and add jO constraint which is an offsetable memory operand valid for APX NDD instructions with immediate operand. Update APX NDD patterns with jM and jO constraints. gcc/ PR target/113711 PR target/113733 * config/i386/constraints.md: List all constraints with j prefix. (j>): Change auto-dec to auto-inc in documentation. (je): Changed to a memory constraint with APX NDD TLS operand check. (jM): New memory constraint for APX NDD instructions. (jO): Likewise. * config/i386/i386-protos.h (x86_poff_operand_p): Removed. * config/i386/i386.cc (x86_poff_operand_p): Likewise. * config/i386/i386.md (*add3_doubleword): Use rjO. (*add_1[SWI48]): Use je and jM. (addsi_1_zext): Use jM. (*addv4_doubleword_1[DWI]): Likewise. (*sub_1[SWI]): Use jM. (@add3_cc_overflow_1[SWI]): Likewise. (*add3_doubleword_cc_overflow_1): Use rjO. (*and3_doubleword): Likewise. (*anddi_1): Use jM. (*andsi_1_zext): Likewise. (*and_1[SWI24]): Likewise. (*3_doubleword[any_or]: Use rjO (*code_1[any_or SWI248]): Use jM. (*si_1_zext[zero_extend + any_or]): Likewise. * config/i386/predicates.md (apx_ndd_memory_operand): New. (apx_ndd_add_memory_operand): Likewise. gcc/testsuite/ PR target/113711 PR target/113733 * gcc.target/i386/apx-ndd-2.c: New test. * gcc.target/i386/apx-ndd-base-index-1.c: Likewise. * gcc.target/i386/apx-ndd-no-seg-global-1.c: Likewise. * gcc.target/i386/apx-ndd-seg-1.c: Likewise. * gcc.target/i386/apx-ndd-seg-2.c: Likewise. * gcc.target/i386/apx-ndd-seg-3.c: Likewise. * gcc.target/i386/apx-ndd-seg-4.c: Likewise. * gcc.target/i386/apx-ndd-seg-5.c: Likewise. * gcc.target/i386/apx-ndd-tls-1a.c: Likewise. * gcc.target/i386/apx-ndd-tls-2.c: Likewise. * gcc.target/i386/apx-ndd-tls-3.c: Likewise. * gcc.target/i386/apx-ndd-tls-4.c: Likewise. * gcc.target/i386/apx-ndd-x32-1.c: Likewise. --- gcc/config/i386/constraints.md | 36 ++++- gcc/config/i386/i386-protos.h | 1 - gcc/config/i386/i386.cc | 25 ---- gcc/config/i386/i386.md | 129 +++++++++--------- gcc/config/i386/predicates.md | 65 +++++++++ gcc/testsuite/gcc.target/i386/apx-ndd-2.c | 17 +++ .../gcc.target/i386/apx-ndd-base-index-1.c | 50 +++++++ .../gcc.target/i386/apx-ndd-no-seg-global-1.c | 74 ++++++++++ gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c | 98 +++++++++++++ gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c | 98 +++++++++++++ gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c | 14 ++ gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c | 9 ++ gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c | 13 ++ .../gcc.target/i386/apx-ndd-tls-1a.c | 41 ++++++ gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c | 38 ++++++ gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c | 16 +++ gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c | 31 +++++ gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c | 49 +++++++ 18 files changed, 712 insertions(+), 92 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-2.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c create mode 100644 gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md index 280e4c8e36c..64702d9c0a8 100644 --- a/gcc/config/i386/constraints.md +++ b/gcc/config/i386/constraints.md @@ -372,6 +372,24 @@ (define_address_constraint "Ts" "Address operand without segment register" (match_operand 0 "address_no_seg_operand")) +;; j prefix is used for APX operand constraints. +;; < Auto-dec memory operand without GPR32. +;; > Auto-inc memory operand without GPR32. +;; a Vector memory operand without GPR32. +;; b VSIB address operand without EGPR. +;; c Integer register. GENERAL_GPR16 for TARGET_APX_EGPR and +;; !TARGET_AVX, otherwise GENERAL_REGS. +;; e Memory operand for APX NDD ADD. +;; j Integer register. GENERAL_GPR16 for TARGET_APX_EGPR, otherwise +;; GENERAL_REGS. +;; o Offsetable memory operand without GPR32. +;; p General address operand without GPR32. +;; m Memory operand without GPR32. +;; M Memory operand, with APX NDD check. +;; R Integer register. GENERAL_REGS. +;; O Offsettable memory operand, with APX NDD check. +;; V Non-offsetable memory operand without GPR32. + ;; Constraint that force to use EGPR, can only adopt to register class. (define_register_constraint "jR" "GENERAL_REGS") @@ -393,7 +411,7 @@ (define_constraint "j<" (match_test "x86_extended_rex2reg_mentioned_p (op)"))))) (define_constraint "j>" - "@internal auto-dec memory operand without GPR32." + "@internal auto-inc memory operand without GPR32." (and (and (match_code "mem") (ior (match_test "GET_CODE (XEXP (op, 0)) == PRE_INC") (match_test "GET_CODE (XEXP (op, 0)) == POST_INC"))) @@ -438,7 +456,15 @@ (define_address_constraint "jb" (define_register_constraint "jc" "TARGET_APX_EGPR && !TARGET_AVX ? GENERAL_GPR16 : GENERAL_REGS") -(define_constraint "je" - "@internal constant that do not allow any unspec global offsets" - (and (match_operand 0 "x86_64_immediate_operand") - (match_test "!x86_poff_operand_p (op)"))) +(define_memory_constraint "je" + "@internal Memory operand for APX NDD ADD." + (match_operand 0 "apx_ndd_add_memory_operand")) + +(define_memory_constraint "jM" + "@internal Memory operand, with APX NDD check." + (match_operand 0 "apx_ndd_memory_operand")) + +(define_memory_constraint "jO" + "@internal Offsettable memory operand, with APX NDD check." + (and (match_operand 0 "apx_ndd_memory_operand") + (match_test "offsettable_nonstrict_memref_p (op)"))) diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h index 34b93773b69..46214a63974 100644 --- a/gcc/config/i386/i386-protos.h +++ b/gcc/config/i386/i386-protos.h @@ -66,7 +66,6 @@ extern bool x86_extended_QIreg_mentioned_p (rtx_insn *); extern bool x86_extended_reg_mentioned_p (rtx); extern bool x86_extended_rex2reg_mentioned_p (rtx); extern bool x86_evex_reg_mentioned_p (rtx [], int); -extern bool x86_poff_operand_p (rtx); extern bool x86_maybe_negate_const_int (rtx *, machine_mode); extern machine_mode ix86_cc_mode (enum rtx_code, rtx, rtx); diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc index b3e7c74846e..706dfe8f5b2 100644 --- a/gcc/config/i386/i386.cc +++ b/gcc/config/i386/i386.cc @@ -23406,31 +23406,6 @@ x86_evex_reg_mentioned_p (rtx operands[], int nops) return false; } -/* Return true when rtx operand does not contain any UNSPEC_*POFF related - constant to avoid APX_NDD instructions excceed encoding length limit. */ -bool -x86_poff_operand_p (rtx operand) -{ - if (GET_CODE (operand) == CONST) - { - rtx op = XEXP (operand, 0); - if (GET_CODE (op) == PLUS) - op = XEXP (op, 0); - - if (GET_CODE (op) == UNSPEC) - { - int unspec = XINT (op, 1); - return (unspec == UNSPEC_NTPOFF - || unspec == UNSPEC_TPOFF - || unspec == UNSPEC_DTPOFF - || unspec == UNSPEC_GOTTPOFF - || unspec == UNSPEC_GOTNTPOFF - || unspec == UNSPEC_INDNTPOFF); - } - } - return false; -} - /* If profitable, negate (without causing overflow) integer constant of mode MODE at location LOC. Return true in this case. */ bool diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index a82f2e456fe..d5db538bb6a 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -6290,10 +6290,10 @@ (define_expand "add3" }) (define_insn_and_split "*add3_doubleword" - [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r") + [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r,&r") (plus: - (match_operand: 1 "nonimmediate_operand" "%0,0,ro,r") - (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,r"))) + (match_operand: 1 "nonimmediate_operand" "%0,0,ro,rjO,r") + (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,,r"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands, TARGET_APX_NDD)" "#" @@ -6332,7 +6332,7 @@ (define_insn_and_split "*add3_doubleword" DONE; } } -[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) +[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")]) (define_insn_and_split "*add3_doubleword_zext" [(set (match_operand: 0 "nonimmediate_operand" "=r,o,&r,&r") @@ -6424,10 +6424,10 @@ (define_insn_and_split "*add3_doubleword_concat_zext" "split_double_mode (mode, &operands[0], 1, &operands[0], &operands[5]);") (define_insn "*add_1" - [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r,r") + [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r,r,r,r") (plus:SWI48 - (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rm,r,m,r") - (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,je,BM"))) + (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r,rje,jM,r") + (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le,r,e,BM"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (PLUS, mode, operands, TARGET_APX_NDD)" { @@ -6462,7 +6462,7 @@ (define_insn "*add_1" : "add{}\t{%2, %0|%0, %2}"; } } - [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd,apx_ndd") + [(set_attr "isa" "*,*,*,*,apx_ndd,apx_ndd,apx_ndd") (set (attr "type") (cond [(eq_attr "alternative" "3") (const_string "lea") @@ -6484,10 +6484,10 @@ (define_insn "*add_1" ;; patterns constructed from addsi_1 to match. (define_insn "addsi_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r,r,r") (zero_extend:DI - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm") - (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,re")))) + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r,r,rm,rjM") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le,rBMe,r,e")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands, TARGET_APX_NDD)" @@ -6523,7 +6523,7 @@ (define_insn "addsi_1_zext" : "add{l}\t{%2, %k0|%k0, %2}"; } } - [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd") + [(set_attr "isa" "*,*,*,apx_ndd,apx_ndd,apx_ndd") (set (attr "type") (cond [(eq_attr "alternative" "2") (const_string "lea") @@ -7463,7 +7463,7 @@ (define_insn_and_split "*addv4_doubleword_1" (eq:CCO (plus: (sign_extend: - (match_operand: 1 "nonimmediate_operand" "%0,rm")) + (match_operand: 1 "nonimmediate_operand" "%0,rjM")) (match_operand: 3 "const_scalar_int_operand" "n,n")) (sign_extend: (plus: @@ -7833,18 +7833,19 @@ (define_insn_and_split "*sub3_doubleword_zext" [(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) (define_insn "*sub_1" - [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r") + [(set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r,r") (minus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,r") - (match_operand:SWI 2 "" ",,r,"))) + (match_operand:SWI 1 "nonimmediate_operand" "0,0,rm,rjM,r") + (match_operand:SWI 2 "" ",,r,,"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (MINUS, mode, operands, TARGET_APX_NDD)" "@ sub{}\t{%2, %0|%0, %2} sub{}\t{%2, %0|%0, %2} sub{}\t{%2, %1, %0|%0, %1, %2} + sub{}\t{%2, %1, %0|%0, %1, %2} sub{}\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd") (set_attr "type" "alu") (set_attr "mode" "")]) @@ -9370,18 +9371,19 @@ (define_insn "@add3_cc_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus:SWI - (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,r") - (match_operand:SWI 2 "" ",,r,")) + (match_operand:SWI 1 "nonimmediate_operand" "%0,0,rm,rjM,r") + (match_operand:SWI 2 "" ",,r,,")) (match_dup 1))) - (set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r") + (set (match_operand:SWI 0 "nonimmediate_operand" "=m,,r,r,r") (plus:SWI (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, mode, operands, TARGET_APX_NDD)" "@ add{}\t{%2, %0|%0, %2} add{}\t{%2, %0|%0, %2} add{}\t{%2, %1, %0|%0, %1, %2} + add{}\t{%2, %1, %0|%0, %1, %2} add{}\t{%2, %1, %0|%0, %1, %2}" - [(set_attr "isa" "*,*,apx_ndd,apx_ndd") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd") (set_attr "type" "alu") (set_attr "mode" "")]) @@ -9501,10 +9503,10 @@ (define_insn_and_split "*add3_doubleword_cc_overflow_1" [(set (reg:CCC FLAGS_REG) (compare:CCC (plus: - (match_operand: 1 "nonimmediate_operand" "%0,0,ro,r") - (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,o")) + (match_operand: 1 "nonimmediate_operand" "%0,0,ro,rjO,r") + (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,,o")) (match_dup 1))) - (set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r") + (set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r,&r") (plus: (match_dup 1) (match_dup 2)))] "ix86_binary_operator_ok (PLUS, mode, operands, TARGET_APX_NDD)" "#" @@ -9546,7 +9548,7 @@ (define_insn_and_split "*add3_doubleword_cc_overflow_1" else operands[6] = gen_rtx_ZERO_EXTEND (mode, operands[5]); } -[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) +[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")]) ;; x == 0 with zero flag test can be done also as x < 1U with carry flag ;; test, where the latter is preferrable if we have some carry consuming @@ -11690,10 +11692,10 @@ (define_expand "and3" }) (define_insn_and_split "*and3_doubleword" - [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r") + [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r,&r") (and: - (match_operand: 1 "nonimmediate_operand" "%0,0,ro,r") - (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,o"))) + (match_operand: 1 "nonimmediate_operand" "%0,0,ro,rjO,r") + (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,,o"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, mode, operands, TARGET_APX_NDD)" "#" @@ -11730,13 +11732,13 @@ (define_insn_and_split "*and3_doubleword" DONE; } -[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) +[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")]) (define_insn "*anddi_1" - [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,?k") + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm,r,r,r,r,r,?k") (and:DI - (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,r,qm,k") - (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,re,m,L,k"))) + (match_operand:DI 1 "nonimmediate_operand" "%0,r,0,0,rm,rjM,r,qm,k") + (match_operand:DI 2 "x86_64_szext_general_operand" "Z,Z,re,m,r,e,m,L,k"))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands, TARGET_APX_NDD)" @@ -11747,11 +11749,12 @@ (define_insn "*anddi_1" and{q}\t{%2, %0|%0, %2} and{q}\t{%2, %1, %0|%0, %1, %2} and{q}\t{%2, %1, %0|%0, %1, %2} + and{q}\t{%2, %1, %0|%0, %1, %2} # #" - [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,x64,avx512bw") - (set_attr "type" "alu,alu,alu,alu,alu,alu,imovx,msklog") - (set_attr "length_immediate" "*,*,*,*,*,*,0,*") + [(set_attr "isa" "x64,apx_ndd,x64,x64,apx_ndd,apx_ndd,apx_ndd,x64,avx512bw") + (set_attr "type" "alu,alu,alu,alu,alu,alu,alu,imovx,msklog") + (set_attr "length_immediate" "*,*,*,*,*,*,*,0,*") (set (attr "prefix_rex") (if_then_else (and (eq_attr "type" "imovx") @@ -11759,7 +11762,7 @@ (define_insn "*anddi_1" (match_operand 1 "ext_QIreg_operand"))) (const_string "1") (const_string "*"))) - (set_attr "mode" "SI,SI,DI,DI,DI,DI,SI,DI")]) + (set_attr "mode" "SI,SI,DI,DI,DI,DI,DI,SI,DI")]) (define_insn_and_split "*anddi_1_btr" [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") @@ -11814,25 +11817,26 @@ (define_split ;; See comment for addsi_1_zext why we do use nonimmediate_operand (define_insn "*andsi_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") (zero_extend:DI - (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r") - (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM")))) + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands, TARGET_APX_NDD)" "@ and{l}\t{%2, %k0|%k0, %2} and{l}\t{%2, %1, %k0|%k0, %1, %2} + and{l}\t{%2, %1, %k0|%k0, %1, %2} and{l}\t{%2, %1, %k0|%k0, %1, %2}" [(set_attr "type" "alu") - (set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd") (set_attr "mode" "SI")]) (define_insn "*and_1" - [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,Ya,?k") - (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,r,qm,k") - (match_operand:SWI24 2 "" "r,,r,,L,k"))) + [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,r,r,r,Ya,?k") + (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,rm,rjM,r,qm,k") + (match_operand:SWI24 2 "" "r,,r,,,L,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (AND, mode, operands, TARGET_APX_NDD)" "@ @@ -11840,19 +11844,20 @@ (define_insn "*and_1" and{}\t{%2, %0|%0, %2} and{}\t{%2, %1, %0|%0, %1, %2} and{}\t{%2, %1, %0|%0, %1, %2} + and{}\t{%2, %1, %0|%0, %1, %2} # #" [(set (attr "isa") - (cond [(eq_attr "alternative" "2,3") + (cond [(eq_attr "alternative" "2,3,4") (const_string "apx_ndd") - (eq_attr "alternative" "5") + (eq_attr "alternative" "6") (if_then_else (eq_attr "mode" "SI") (const_string "avx512bw") (const_string "avx512f")) ] (const_string "*"))) - (set_attr "type" "alu,alu,alu,alu,imovx,msklog") - (set_attr "length_immediate" "*,*,*,*,0,*") + (set_attr "type" "alu,alu,alu,alu,alu,imovx,msklog") + (set_attr "length_immediate" "*,*,*,*,*,0,*") (set (attr "prefix_rex") (if_then_else (and (eq_attr "type" "imovx") @@ -11860,7 +11865,7 @@ (define_insn "*and_1" (match_operand 1 "ext_QIreg_operand"))) (const_string "1") (const_string "*"))) - (set_attr "mode" ",,,,SI,")]) + (set_attr "mode" ",,,,,SI,")]) (define_insn "*andqi_1" [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r,r,?k") @@ -12677,10 +12682,10 @@ (define_expand "3" }) (define_insn_and_split "*3_doubleword" - [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r") + [(set (match_operand: 0 "nonimmediate_operand" "=ro,r,&r,&r,&r") (any_or: - (match_operand: 1 "nonimmediate_operand" "%0,0,ro,r") - (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,o"))) + (match_operand: 1 "nonimmediate_operand" "%0,0,ro,rjO,r") + (match_operand: 2 "x86_64_hilo_general_operand" "r,o,r,,o"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (, mode, operands, TARGET_APX_NDD)" "#" @@ -12733,13 +12738,13 @@ (define_insn_and_split "*3_doubleword" DONE; } -[(set_attr "isa" "*,*,apx_ndd,apx_ndd")]) +[(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd")]) (define_insn "*_1" - [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,?k") + [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,r,r,r,?k") (any_or:SWI248 - (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,r,k") - (match_operand:SWI248 2 "" "r,,r,,k"))) + (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,rm,rjM,r,k") + (match_operand:SWI248 2 "" "r,,r,,,k"))) (clobber (reg:CC FLAGS_REG))] "ix86_binary_operator_ok (, mode, operands, TARGET_APX_NDD)" "@ @@ -12747,9 +12752,10 @@ (define_insn "*_1" {}\t{%2, %0|%0, %2} {}\t{%2, %1, %0|%0, %1, %2} {}\t{%2, %1, %0|%0, %1, %2} + {}\t{%2, %1, %0|%0, %1, %2} #" - [(set_attr "isa" "*,*,apx_ndd,apx_ndd,") - (set_attr "type" "alu, alu, alu, alu, msklog") + [(set_attr "isa" "*,*,apx_ndd,apx_ndd,apx_ndd,") + (set_attr "type" "alu, alu, alu, alu, alu, msklog") (set_attr "mode" "")]) (define_insn_and_split "*notxor_1" @@ -12864,19 +12870,20 @@ (define_insn_and_split "*xor2andn" ;; See comment for addsi_1_zext why we do use nonimmediate_operand (define_insn "*si_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r,r") + [(set (match_operand:DI 0 "register_operand" "=r,r,r,r") (zero_extend:DI - (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,r") - (match_operand:SI 2 "x86_64_general_operand" "rBMe,re,BM")))) + (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0,rm,rjM,r") + (match_operand:SI 2 "x86_64_general_operand" "rBMe,r,e,BM")))) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && ix86_binary_operator_ok (, SImode, operands, TARGET_APX_NDD)" "@ {l}\t{%2, %k0|%k0, %2} {l}\t{%2, %1, %k0|%k0, %1, %2} + {l}\t{%2, %1, %k0|%k0, %1, %2} {l}\t{%2, %1, %k0|%k0, %1, %2}" [(set_attr "type" "alu") - (set_attr "isa" "*,apx_ndd,apx_ndd") + (set_attr "isa" "*,apx_ndd,apx_ndd,apx_ndd") (set_attr "mode" "SI")]) (define_insn "*si_1_zext_imm" diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md index 06027a84532..4c1aedd7e70 100644 --- a/gcc/config/i386/predicates.md +++ b/gcc/config/i386/predicates.md @@ -2248,3 +2248,68 @@ (define_predicate "aeswidekl_operation" } return true; }) + +;; Return true if OP is a memory operand that can be also used in APX +;; NDD patterns with immediate operand. With non-default address space, +;; segment register or address size prefix, APX NDD instruction length +;; can exceed the 15 byte size limit. +(define_predicate "apx_ndd_memory_operand" + (match_operand 0 "memory_operand") +{ + /* OK if immediate operand size < 4 bytes. */ + if (GET_MODE_SIZE (mode) < 4) + return true; + + bool default_addr = ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (op)); + bool address_size_prefix = TARGET_X32 && Pmode == SImode; + + struct ix86_address parts; + int ok; + + op = XEXP (op, 0); + ok = ix86_decompose_address (op, &parts); + gcc_assert (ok); + + if (default_addr) + { + /* Default address space. */ + + /* Not OK with address size prefix, index register and disp. */ + if (address_size_prefix + && parts.index + && parts.disp + && parts.disp != const0_rtx) + return false; + } + else + { + /* Non-default address space. */ + + /* Not OK without base register. */ + if (!parts.base) + return false; + + /* Not OK with disp and address size prefix. */ + if (address_size_prefix && parts.disp) + return false; + } + + return true; +}) + +;; Return true if OP is a memory operand which can be used in APX NDD +;; ADD with register source operand. UNSPEC_GOTNTPOFF memory operand +;; isn't allowed with APX NDD ADD. +(define_predicate "apx_ndd_add_memory_operand" + (match_operand 0 "memory_operand") +{ + op = XEXP (op, 0); + + /* Disallow APX NDD ADD with UNSPEC_GOTNTPOFF. */ + if (GET_CODE (op) == CONST + && GET_CODE (XEXP (op, 0)) == UNSPEC + && XINT (XEXP (op, 0), 1) == UNSPEC_GOTNTPOFF) + return false; + + return true; +}) diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-2.c b/gcc/testsuite/gcc.target/i386/apx-ndd-2.c new file mode 100644 index 00000000000..3a5272d065e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-2.c @@ -0,0 +1,17 @@ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O3 -w" } */ + +long a; +int b, d, e; +void +g (void) +{ + int c; + _Bool f; + __asm__("" : "=c"(c)); + switch (d) + case 2: + e = f = c & 2; + if (f) + a = b; +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c b/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c new file mode 100644 index 00000000000..208acd36958 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-base-index-1.c @@ -0,0 +1,50 @@ +/* PR target/113711 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +#define FOO(TYPE, OP_NAME, OP, IMM) \ +TYPE \ +foo_##OP_NAME##_##TYPE (TYPE *p, int64_t off) \ +{ \ + TYPE b = p[off] OP IMM; \ + return b; \ +} + +FOO (char, add, +, 0x7) +FOO (short, add, +, 0x2000) +FOO (int, add, +, 0x2000) +FOO (int64_t, add, +, 0x2000) + +FOO (char, sub, -, 0x7) +FOO (short, sub, -, 0x2000) +FOO (int, sub, -, 0x2000) +FOO (int64_t, sub, -, 0x2000) + +FOO (char, and, &, 0x7) +FOO (short, and, &, 0x2000) +FOO (int, and, &, 0x2000) +FOO (int64_t, and, &, 0x2000) + +FOO (char, or, |, 0x7) +FOO (short, or, |, 0x2000) +FOO (int, or, |, 0x2000) +FOO (int64_t, or, |, 0x2000) + +FOO (char, xor, ^, 0x7) +FOO (short, xor, ^, 0x2000) +FOO (int, xor, ^, 0x2000) +FOO (int64_t, xor, ^, 0x2000) + +FOO (char, shl, <<, 0x7) +FOO (short, shl, <<, 0x7) +FOO (int, shl, <<, 0x7) +FOO (int64_t, shl, <<, 0x7) + +FOO (char, sar, >>, 0x7) +FOO (short, sar, >>, 0x7) +FOO (int, sar, >>, 0x7) +FOO (int64_t, sar, >>, 0x7) + +/* { dg-final { scan-assembler-not "mov"} } */ diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c b/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c new file mode 100644 index 00000000000..d2a4040975a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-no-seg-global-1.c @@ -0,0 +1,74 @@ +/* PR target/113711 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +#define FOO(TYPE, OP_NAME, OP, IMM) \ +extern TYPE foo_##OP_NAME##_##TYPE##_var; \ +TYPE \ +foo_##OP_NAME##_##TYPE (void) \ +{ \ + TYPE b = foo_##OP_NAME##_##TYPE##_var OP IMM; \ + return b; \ +} + +#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \ +extern UTYPE bar_##OP_NAME##_##TYPE##_var; \ +int64_t \ +bar_##OP_NAME##_##TYPE (void) \ +{ \ + int64_t b = bar_##OP_NAME##_##TYPE##_var OP IMM; \ + return b; \ +} + +FOO (char, add, +, 0x7) +FOO (short, add, +, 0x2000) +FOO (int, add, +, 0x2000) +BAR (int, unsigned int, add, +, 0x2000) +FOO (int64_t, add, +, 0x2000) +BAR (int64_t, uint64_t, add, +, 0x2000) + +FOO (char, sub, -, 0x7) +FOO (short, sub, -, 0x2000) +FOO (int, sub, -, 0x2000) +BAR (int, unsigned int, sub, -, 0x2000) +FOO (int64_t, sub, -, 0x2000) +BAR (int64_t, uint64_t, sub, -, 0x2000) + +FOO (char, and, &, 0x7) +FOO (short, and, &, 0x2000) +FOO (int, and, &, 0x2000) +BAR (int, unsigned int, and, &, 0x2000) +FOO (int64_t, and, &, 0x2000) +BAR (int64_t, uint64_t, and, &, 0x2000) + +FOO (char, or, |, 0x7) +FOO (short, or, |, 0x2000) +FOO (int, or, |, 0x2000) +BAR (int, unsigned int, or, |, 0x2000) +FOO (int64_t, or, |, 0x2000) +BAR (int64_t, uint64_t, or, |, 0x2000) + +FOO (char, xor, ^, 0x7) +FOO (short, xor, ^, 0x2000) +FOO (int, xor, ^, 0x2000) +BAR (int, unsigned int, xor, ^, 0x2000) +FOO (int64_t, xor, ^, 0x2000) +BAR (int64_t, uint64_t, xor, ^, 0x2000) + +FOO (char, shl, <<, 0x7) +FOO (short, shl, <<, 0x7) +FOO (int, shl, <<, 0x7) +BAR (int, unsigned int, shl, <<, 0x7) +FOO (int64_t, shl, <<, 0x7) +BAR (int64_t, uint64_t, shl, <<, 0x7) + +FOO (char, sar, >>, 0x7) +FOO (short, sar, >>, 0x7) +FOO (int, sar, >>, 0x7) +BAR (int, unsigned int, sar, >>, 0x7) +FOO (int64_t, sar, >>, 0x7) +BAR (int64_t, uint64_t, sar, >>, 0x7) + +/* { dg-final { scan-assembler-not "mov"} } */ diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c new file mode 100644 index 00000000000..d18055a9250 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-1.c @@ -0,0 +1,98 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +#define FOO(TYPE, OP_NAME, OP, IMM) \ +TYPE \ +foo_##OP_NAME##_##TYPE (void) \ +{ \ + TYPE b = (*(TYPE __seg_fs *) 0) OP IMM; \ + return b; \ +} + +#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \ +int64_t \ +bar_##OP_NAME##_##TYPE (void) \ +{ \ + int64_t b = (*(UTYPE __seg_fs *) 0) OP IMM; \ + return b; \ +} + +FOO (char, add, +, 0x7) +BAR (char, unsigned char, add, +, 0x7) +FOO (short, add, +, 0x2000) +BAR (short, unsigned short, add, +, 0x2000) +FOO (int, add, +, 0x2000) +BAR (int, unsigned int, add, +, 0x2000) +FOO (int64_t, add, +, 0x2000) +BAR (int64_t, uint64_t, add, +, 0x2000) +FOO (__int128_t, add, +, 0x2000) +BAR (__int128_t, __uint128_t, add, +, 0x2000) + +FOO (char, sub, -, 0x7) +BAR (char, unsigned char, sub, -, 0x7) +FOO (short, sub, -, 0x2000) +BAR (short, unsigned short, sub, -, 0x2000) +FOO (int, sub, -, 0x2000) +BAR (int, unsigned int, sub, -, 0x2000) +FOO (int64_t, sub, -, 0x2000) +BAR (int64_t, uint64_t, sub, -, 0x2000) +FOO (__int128_t, sub, -, 0x2000) +BAR (__int128_t, __uint128_t, sun, -, 0x2000) + +FOO (char, and, &, 0x7) +BAR (char, unsigned char, and, &, 0x7) +FOO (short, and, &, 0x2000) +BAR (short, unsigned short, and, &, 0x2000) +FOO (int, and, &, 0x2000) +BAR (int, unsigned int, and, &, 0x2000) +FOO (int64_t, and, &, 0x2000) +BAR (int64_t, uint64_t, and, &, 0x2000) +FOO (__int128_t, and, &, 0x2000) +BAR (__int128_t, __uint128_t, and, &, 0x2000) + +FOO (char, or, |, 0x7) +BAR (char, unsigned char, or, |, 0x7) +FOO (short, or, |, 0x2000) +BAR (short, unsigned short, or, |, 0x2000) +FOO (int, or, |, 0x2000) +BAR (int, unsigned int, or, |, 0x2000) +FOO (int64_t, or, |, 0x2000) +BAR (int64_t, uint64_t, or, |, 0x2000) +FOO (__int128_t, or, |, 0x2000) +BAR (__int128_t, __uint128_t, or, |, 0x2000) + +FOO (char, xor, ^, 0x7) +BAR (char, unsigned char, xor, ^, 0x7) +FOO (short, xor, ^, 0x2000) +BAR (short, unsigned short, xor, ^, 0x2000) +FOO (int, xor, ^, 0x2000) +BAR (int, unsigned int, xor, ^, 0x2000) +FOO (int64_t, xor, ^, 0x2000) +BAR (int64_t, uint64_t, xor, ^, 0x2000) +FOO (__int128_t, xor, ^, 0x2000) +BAR (__int128_t, __uint128_t, xor, ^, 0x2000) + +FOO (char, shl, <<, 0x7) +BAR (char, unsigned char, shl, <<, 0x7) +FOO (short, shl, <<, 0x7) +BAR (short, unsigned short, shl, <<, 0x7) +FOO (int, shl, <<, 0x7) +BAR (int, unsigned int, shl, <<, 0x7) +FOO (int64_t, shl, <<, 0x7) +BAR (int64_t, uint64_t, shl, <<, 0x7) +FOO (__int128_t, shl, <<, 0x7) +BAR (__int128_t, __uint128_t, shl, <<, 0x7) + +FOO (char, sar, >>, 0x7) +BAR (char, unsigned char, sar, >>, 0x7) +FOO (short, sar, >>, 0x7) +BAR (short, unsigned short, sar, >>, 0x7) +FOO (int, sar, >>, 0x7) +BAR (int, unsigned int, sar, >>, 0x7) +FOO (int64_t, sar, >>, 0x7) +BAR (int64_t, uint64_t, sar, >>, 0x7) +FOO (__int128_t, sar, >>, 0x7) +BAR (__int128_t, __uint128_t, sar, >>, 0x7) diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c new file mode 100644 index 00000000000..5b164ef79a7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-2.c @@ -0,0 +1,98 @@ +/* PR target/113711 */ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +#define FOO(TYPE, OP_NAME, OP, IMM) \ +TYPE \ +foo_##OP_NAME##_##TYPE (void) \ +{ \ + TYPE b = (*(TYPE *) 0x20000) OP IMM; \ + return b; \ +} + +#define BAR(TYPE, UTYPE, OP_NAME, OP, IMM) \ +int64_t \ +bar_##OP_NAME##_##TYPE (void) \ +{ \ + int64_t b = (*(UTYPE *) 0x20000) OP IMM; \ + return b; \ +} + +#define SEG(TYPE, OP_NAME, OP, IMM) \ +TYPE \ +seg_##OP_NAME##_##TYPE (void) \ +{ \ + TYPE b = (*(TYPE __seg_fs *) 0) OP IMM; \ + return b; \ +} + +FOO (char, add, +, 0x7) +SEG (char, add, +, 0x7) +FOO (short, add, +, 0x2000) +SEG (short, add, +, 0x2000) +FOO (int, add, +, 0x2000) +BAR (int, unsigned int, add, +, 0x2000) +FOO (int64_t, add, +, 0x2000) +BAR (int64_t, uint64_t, add, +, 0x2000) + +FOO (char, sub, -, 0x7) +SEG (char, sub, -, 0x7) +FOO (short, sub, -, 0x2000) +SEG (short, sub, -, 0x2000) +FOO (int, sub, -, 0x2000) +BAR (int, unsigned int, sub, -, 0x2000) +FOO (int64_t, sub, -, 0x2000) +BAR (int64_t, uint64_t, sub, -, 0x2000) + +FOO (char, and, &, 0x7) +SEG (char, and, &, 0x7) +FOO (short, and, &, 0x2000) +SEG (short, and, &, 0x2000) +FOO (int, and, &, 0x2000) +BAR (int, unsigned int, and, &, 0x2000) +FOO (int64_t, and, &, 0x2000) +BAR (int64_t, uint64_t, and, &, 0x2000) + +FOO (char, or, |, 0x7) +SEG (char, or, |, 0x7) +FOO (short, or, |, 0x2000) +SEG (short, or, |, 0x2000) +FOO (int, or, |, 0x2000) +BAR (int, unsigned int, or, |, 0x2000) +FOO (int64_t, or, |, 0x2000) +BAR (int64_t, uint64_t, or, |, 0x2000) + +FOO (char, xor, ^, 0x7) +SEG (char, xor, ^, 0x7) +FOO (short, xor, ^, 0x2000) +SEG (short, xor, ^, 0x2000) +FOO (int, xor, ^, 0x2000) +BAR (int, unsigned int, xor, ^, 0x2000) +FOO (int64_t, xor, ^, 0x2000) +BAR (int64_t, uint64_t, xor, ^, 0x2000) + +FOO (char, shl, <<, 0x7) +SEG (char, shl, <<, 0x7) +FOO (short, shl, <<, 0x7) +SEG (short, shl, <<, 0x7) +FOO (int, shl, <<, 0x7) +SEG (int, shl, <<, 0x7) +BAR (int, unsigned int, shl, <<, 0x7) +FOO (int64_t, shl, <<, 0x7) +SEG (int64_t, shl, <<, 0x7) +BAR (int64_t, uint64_t, shl, <<, 0x7) + +FOO (char, sar, >>, 0x7) +SEG (char, sar, >>, 0x7) +FOO (short, sar, >>, 0x7) +SEG (short, sar, >>, 0x7) +FOO (int, sar, >>, 0x7) +SEG (int, sar, >>, 0x7) +BAR (int, unsigned int, sar, >>, 0x7) +FOO (int64_t, sar, >>, 0x7) +SEG (int64_t, sar, >>, 0x7) +BAR (int64_t, uint64_t, sar, >>, 0x7) + +/* { dg-final { scan-assembler-not "mov"} } */ diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c new file mode 100644 index 00000000000..e7d9c3ca11a --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-3.c @@ -0,0 +1,14 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O2" } */ + +typedef signed __int128 S; +int o; + +S +qux (void) +{ + S z; + o = __builtin_add_overflow (*(S __seg_fs *) 0x1000, 0x200, &z); + return z; +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c new file mode 100644 index 00000000000..a60c4d7d9b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-4.c @@ -0,0 +1,9 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O2" } */ + +unsigned __int128 +foo (void) +{ + return *((unsigned __int128 __seg_fs *) 0x1000) + 0x2000; +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c new file mode 100644 index 00000000000..9be4e96767c --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-seg-5.c @@ -0,0 +1,13 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +extern int bar __attribute__((__visibility__ ("hidden"))); + +uintptr_t +foo (void) +{ + return (*(uintptr_t __seg_fs *) 0x1000) - (uintptr_t) &bar; +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c new file mode 100644 index 00000000000..5bf57a76ef7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-1a.c @@ -0,0 +1,41 @@ +/* PR target/113733 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-mapxf -O3 -w" } */ + +extern __thread int a, j; +enum b +{ + c, + d +}; +struct e +{ + long f; + struct + { + char g[1024]; + }; +} typedef h (); +long i; +int o (char *); +static enum b +k (int *p) +{ + h l; + struct e n; + do + { + l (n, n.f, p); + char **m; + for (; *m; ++m) + if (o (*m)) + i = j; + } + while (d); +} +void +getgrouplist () +{ + k (&a); +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c new file mode 100644 index 00000000000..db985940a54 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-2.c @@ -0,0 +1,38 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-mapxf -O2" } */ + +#include + +#define DECL(TYPE) \ +__thread TYPE TYPE##_a = 255; \ +TYPE * volatile TYPE##_a_in_other_thread = (TYPE *)12345; + +DECL(uint64_t) +DECL(uint32_t) + +#define FOO(TYPE, name, op, val) \ +void * \ +thread_func##TYPE##name (void *arg) \ +{ \ + TYPE##_a_in_other_thread = &TYPE##_a; \ + TYPE##_a = TYPE##_a op val; \ + *((TYPE *) arg) = TYPE##_a; \ + return (void *)0; \ +} + +FOO(uint64_t, add, +, 0x2000) +FOO(uint32_t, add, +, 0x2000) + +FOO(uint64_t, sub, -, 0x2000) +FOO(uint32_t, sub, -, 0x2000) + +FOO(uint64_t, or, |, 0x2000) +FOO(uint32_t, or, |, 0x2000) + +FOO(uint64_t, and, &, 0x2000) +FOO(uint32_t, and, &, 0x2000) + +FOO(uint64_t, xor, ^, 0x2000) +FOO(uint32_t, xor, ^, 0x2000) diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c new file mode 100644 index 00000000000..e7374b44825 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-3.c @@ -0,0 +1,16 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-mapxf -O2" } */ + +typedef signed __int128 S; +__thread S var; +int o; + +S +qux (void) +{ + S z; + o = __builtin_add_overflow (var, 0x200, &z); + return z; +} diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c new file mode 100644 index 00000000000..f3b2eac6a60 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-tls-4.c @@ -0,0 +1,31 @@ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-require-effective-target tls } */ +/* { dg-options "-mapxf -O2" } */ + +#define DECL(TYPE) \ +extern __thread TYPE TYPE##_a; + +DECL(__int128_t) +DECL(__uint128_t) + +#define FOO(TYPE, name, op, val) \ +TYPE \ +thread_func##TYPE##name (void) \ +{ \ + return TYPE##_a op val; \ +} + +FOO(__int128_t, add, +, 0x2000) +FOO(__uint128_t, add, +, 0x2000) + +FOO(__int128_t, sub, -, 0x2000) +FOO(__uint128_t, sub, -, 0x2000) + +FOO(__int128_t, or, |, 0x2000) +FOO(__uint128_t, or, |, 0x2000) + +FOO(__int128_t, and, &, 0x2000) +FOO(__uint128_t, and, &, 0x2000) + +FOO(__int128_t, xor, ^, 0x2000) +FOO(__uint128_t, xor, ^, 0x2000) diff --git a/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c b/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c new file mode 100644 index 00000000000..4280d400458 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/apx-ndd-x32-1.c @@ -0,0 +1,49 @@ +/* PR target/113711 */ +/* { dg-do assemble { target { apxf && { ! ia32 } } } } */ +/* { dg-require-effective-target maybe_x32 } */ +/* { dg-options "-mapxf -O2 -mx32" } */ + +#include + +#define FOO(TYPE, OP_NAME, OP, IMM) \ +TYPE \ +foo_##OP_NAME##_##TYPE (int off, TYPE *ptr) \ +{ \ + TYPE b = ptr[off + 0x100] + IMM; \ + return b; \ +} + +FOO (char, add, +, 0x7) +FOO (short, add, +, 0x2000) +FOO (int, add, +, 0x2000) +FOO (int64_t, add, +, 0x2000) + +FOO (char, sub, -, 0x7) +FOO (short, sub, -, 0x2000) +FOO (int, sub, -, 0x2000) +FOO (int64_t, sub, -, 0x2000) + +FOO (char, and, &, 0x7) +FOO (short, and, &, 0x2000) +FOO (int, and, &, 0x2000) +FOO (long, and, &, 0x2000) + +FOO (char, or, |, 0x7) +FOO (short, or, |, 0x2000) +FOO (int, or, |, 0x2000) +FOO (int64_t, or, |, 0x2000) + +FOO (char, xor, ^, 0x7) +FOO (short, xor, ^, 0x2000) +FOO (int, xor, ^, 0x2000) +FOO (long, xor, ^, 0x2000) + +FOO (char, shl, <<, 0x7) +FOO (short, shl, <<, 0x7) +FOO (int, shl, <<, 0x7) +FOO (int64_t, shl, <<, 0x7) + +FOO (char, sar, >>, 0x7) +FOO (short, sar, >>, 0x7) +FOO (int, sar, >>, 0x7) +FOO (int64_t, sar, >>, 0x7)