From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpout140.security-mail.net (smtpout140.security-mail.net [85.31.212.148]) by sourceware.org (Postfix) with ESMTPS id AE6503858436 for ; Mon, 17 Jul 2023 09:03:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org AE6503858436 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=kalrayinc.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=kalrayinc.com Received: from localhost (fx408.security-mail.net [127.0.0.1]) by fx408.security-mail.net (Postfix) with ESMTP id AF86B322A0A for ; Mon, 17 Jul 2023 11:03:38 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kalrayinc.com; s=sec-sig-email; t=1689584618; bh=8a8jCj5AZApdpGb963aG3uuSB2TDQ8rCP00jkiXrmOg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=YeXeG1SHZJvrC0KeYs6TrbZkRu7r2Lh13sJpltmDSW6HLMOF2vjbRB7o1rG/6gSzz DLq2FkBHzngpyd3l1RkA9awE1M4muKcQMzrKCehXFfk+PLvPEbu1Dft9869xm89SSe GxXznt/OBbB51Kvsw1ZGFUG0YQbuQCPihZ1wOO1g= Received: from fx408 (fx408.security-mail.net [127.0.0.1]) by fx408.security-mail.net (Postfix) with ESMTP id 8DCBB32297C for ; Mon, 17 Jul 2023 11:03:38 +0200 (CEST) Received: from FRA01-PR2-obe.outbound.protection.outlook.com (mail-pr2fra01lp0100.outbound.protection.outlook.com [104.47.24.100]) by fx408.security-mail.net (Postfix) with ESMTPS id 126B8322A25 for ; Mon, 17 Jul 2023 11:03:38 +0200 (CEST) Received: from MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM (2603:10a6:500:11::21) by PAZP264MB3040.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:1e7::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6588.32; Mon, 17 Jul 2023 09:03:36 +0000 Received: from MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM ([fe80::a854:17f0:8f2a:f6d9]) by MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM ([fe80::a854:17f0:8f2a:f6d9%4]) with mapi id 15.20.6588.031; Mon, 17 Jul 2023 09:03:36 +0000 X-Virus-Scanned: E-securemail Secumail-id: <12739.64b503ea.11b5d.0> ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=EKqjh/NbO1oC2YWEOpGTzuzrHAVltTMAbhhyeD38x4sxtgQEpHMriAHbKBZ3Jrj4uZf9PzlEf0BTOqnOccu0zhnosnp6uKZ4gX6m0F4/o4bwRnyA2fSewMvmvPO9jDvb1RdT4V6/wQtrPpYhebkn3q7xlDZGp8LXqWlh0htTaQriTZRR0LwUlphAho2u0ztMi6GaokHTVcvJQsJMagiR+lwZw8wzq1iiZL/ssWLJdplKsI8bowGP99Cq4Kermqv/HBhiEmpRkhVRBqnodiXU230ymxAkf/9p/OQSZTIpYOlevK5uwV7LIOgDQ6bKvAvWQGXaKc95XBez3tSRsR6R/w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=rGjt6WP1YdrRth348s3e9PetNdts9K+0WG+K4wzVFCQ=; b=er1PRg5YBH1lkB2nscxbMH1fOIep8PQhqFqGuGrrWk/Rx3Y97oRZqaMSd07erlPzeHINDL7Hzl/xSr/SADbXWPr4RNjAOCdJ9pnXxaACY8q1CRMBr+kRD5lvWPmx5opbI/xsBiytAIdKEaJfgF+xbur1jeCxXrpxLc3M/RSsd5uFYPHdbVeMHxXLzityVyp/B18lwPwtG0dZ43K0dfD6ejeVVMV5LSjecHmuaR5T+xpzTLiQtEFdGLKrFxzrlOPaQbmEhUeEof4iMh/koGoy+/xGBvApCmMULZ92YPp36bdAU1QeK1yKpdEmxnuNCoetFf0UoeVj+nKUYw3TD4yyNQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=kalrayinc.com; dmarc=pass action=none header.from=kalrayinc.com; dkim=pass header.d=kalrayinc.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kalrayinc.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=rGjt6WP1YdrRth348s3e9PetNdts9K+0WG+K4wzVFCQ=; b=YnRiIMLgpvdH1QSGoEgRS/3oxgxLWIKDPMXKAUaP5WzcJTv8AxGwTXpUhQE8Le4RhIWHEELkAEGxUKJij3oxAP7BpgW6XiSMv0ftJLMYxwnm/tNitREVX5yoguOGlRl7sF7bb/Le2LiztScEbag75/jMqgShuympEvzZ/6lWlCtUD0aMfn6x7c/CIhfNxyo8wjxeiYpraNdPh6VDjITI5ebimmjHc5ijBM6tg9c60t7AgwqOBmSOQX0F4AyhQoc+T+2HN0KgW1s9zwsYLhZ18bP7bKHLstgAL//ZIPR1WuVtWvDyuetciqIklQXcYY7nOXtNP4Beps+EjGXfEuO7Ag== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=kalrayinc.com; From: Sylvain Noiry To: gcc-patches@gcc.gnu.org Cc: Sylvain Noiry Subject: [PATCH 2/9] Native complex operations: Move functions to hooks Date: Mon, 17 Jul 2023 11:02:43 +0200 Message-ID: <20230717090250.4645-3-snoiry@kalrayinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230717090250.4645-1-snoiry@kalrayinc.com> References: <20230717090250.4645-1-snoiry@kalrayinc.com> X-ClientProxiedBy: LO2P265CA0311.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a5::35) To MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM (2603:10a6:500:11::21) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MR2P264MB0113:EE_|PAZP264MB3040:EE_ X-MS-Office365-Filtering-Correlation-Id: 429b0d4a-0cf3-4790-0bfd-08db86a4b47a X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: BLgkggVo6HvgZUWCEFZanitfE/sO/AeFzijHWxOWWtG8tWnYP+nz1o0NOOp+u46CfYSDL9uPFG3S8ITLZQmg2ZdCbdfSBmny/BvRQiF1YWhdLuT87+IeqROWZ/jhlLzvabjSIsxZ57j06uCzv6yvTvFHcRkw9aww8h56m/oYNc+27opH1XtTwfP+w5YLmExt3XIRZU/J3jd2VBYFTSrfuNyTNLMLaPl09HcH58UY6P8DUfD1S9gUGqlg5oOiMIOxTswB8Hpy2DW4FzD8dbvgIayfsMlno0NrfmzUYNdcFlvQ0lcCd35oZku0z0Jz597BLUL7QVUqobEis4Xu8KMlqHR49LOnFbwwXffX80YjrKo8/jFFODsx5IGfAiOWKGwRKEGY105jkd6y29vDmF0jZ+yEv3x2Md0O9ObG3gHV0+r5lokya5iMfz/JIZy/jpv8gHHoKVxVKFna7rqlvjWSbCNX2Mk/Zjb7ZEBaFHq9I+wTEBQAVwaD8oW1DdyE52aAmnxMXWRdqWMa9SCruurH6ympGwxyHyJoO1qrXvFYTMlujw1wDMQEG0CzcHheVl5L X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230028)(4636009)(396003)(366004)(346002)(136003)(39850400004)(376002)(451199021)(478600001)(6486002)(6666004)(186003)(1076003)(6506007)(26005)(6512007)(107886003)(2906002)(30864003)(41300700001)(316002)(6916009)(4326008)(66476007)(66946007)(66556008)(5660300002)(36756003)(8676002)(8936002)(38100700002)(86362001)(2616005)(83380400001);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: DKElO8pK74u//uRXgejtmqQOxyAjliKO7mAqdA97n0cOcdTroQKicUNKoOs47P6Qzdv9NFXMHC33GuqhIYtleRmbjBOAUtxLOP5TmJF0I1xDftu/PxRWBd+Go5UWrDO9x4ivPz5dYZ531Pb5ertVAS5kWU8GpAb2jtl/MzCUZZb+i9L8OWHEZn/ymYuFz6MpzTNZWXlVTgGm81zfFwmBRQXhAhgPRRy6AahHx1NobKH0w35KyrCNsAM4T20U6KYwmIlz2gORGuJcOo7UGXZcBEoJNeslmBPiFNjMTlCnQ9z87/PYJiFV78JkkyphXnkzMI2+2v1NMxRH7ELHj98SZuuGw45ik1NF1MNE/6WWOpv9O59wVsF4nlZTJgRE3OfGuTZctjV3wxFj/l671nt5Q6bT15mRyv0ky0dAeLVBsOgweEiY+P3rFwYJPzeWH/NG4dkyGs9JPdguhlVnbaySzrBbY8RR6BtEkt8gjNPxlbKhj0l7ehkZN1RHhbtLVPtnxQwMPEKIv1mD91VF0KhL33cxL1xsyxLOeP0KKOCDY8iLQVKDo1vHy70p6vN1bjsMgeKAsa6K8PS9vz22jF7sfOwwhsjWoJjcXGISlxozcAwzOTk+VaySNqTRfbLIJP5hspok+NQrOl1O9kPocS/4XwpVbdHA7p+56IuDycL+DjiJgqAso+vhz+EfxCYK388rsX6WiLGPzx2lhkcJRdsm+zpJswsfw4+xtS++HDn2EB+ubOCPdWV0J7u9NGngrfGxjCBysvVqZi9h/GYYIfHboX1V4R5ss9Y8eoE/SQ9D7k2VmkLqnAHBnt8WKKOwmsiFeKhE6RRDqi/dcmvYPp95Y6Vt9d1dfvoGb0OBDCJTm6cXYOnLHbO9i5OOLKF+Qa+qIaAZvmgBlBAUrdHL/crsAqaxrXiQqIzph/i9lSGFb3Hlox5lX3wuIib5NcQc1b7L ZTMkORBsdQ8gCAcr9yfzgC3wuBX77xAqtk6IEdhLGOsPH9YojWlIAtwKfg918Y77JEmZmSvZE0zJsGlDuENGYPLQZ8wLNmLKSttQZsoz7NytRxvOQqIEYf6fWkVshP5rR7vCzZQfSr35zTO6vgDNhkdGe1T6EFD8aBbO1kqoPAi94BH2sTiGxaeXWrcyQEDr3zoX0i/rL2SO9LhVobgy/p9UK8z5NAIMw3ja2gJx19PLU/FdIaUv8E/dQpDGjl8Rg756DnFDKV5L9PZNCE5lDvsn04bbP4Om91bpvWaZBtGyqQly43K3y93Dsaa+e/wrlyCSbDh0yeGrQ9OcIxttvXjmZbxSre0XjRKYsiyc7tUPZ1E3A9uOxdC0rY5cE+v/akEMVqVPK2cxkytu5rV85a4MrUam32fAevf4AmG7696EZezQaJGt23Y0IDILapi5tT/kLff2s9iG3crIC4fw5Ezro1ICT5mrkrP0ODiKA/dXUHp14ylmggWDJtHb8ez+WLAKyXuIJqSiBKZBaaNS+zkQJVgWGDOLrno3AvbsHzHTk3eU0p6J/SlGngcIRoorVEzy5IBFYoF1SY+zETZ/FBMX8xrVtP4NuwVlaE/w80c4ZMq6hNQfQgOOQ3uQHj7e X-OriginatorOrg: kalrayinc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 429b0d4a-0cf3-4790-0bfd-08db86a4b47a X-MS-Exchange-CrossTenant-AuthSource: MR2P264MB0113.FRAP264.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jul 2023 09:03:36.4854 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 8931925d-7620-4a64-b7fe-20afd86363d3 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0Fu1WNhoPMN0bCo+yUmqu4ygOjKgniQUgxvR8u6V5uwjffTDJOh+edbMXjBzxEPrGUBaU2+lsyaofkJ8+evudw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PAZP264MB3040 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-ALTERMIMEV2_out: done X-Spam-Status: No, score=-10.2 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,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 List-Id: Move read_complex_part and write_complex_part to target hooks. Their signature also change because of the type of argument part is now complex_part_t. Calls to theses functions are updated accordingly. gcc/ChangeLog: * target.def: Define hooks for read_complex_part and write_complex_part * targhooks.cc (default_read_complex_part): New: default implementation of read_complex_part (default_write_complex_part): New: default implementation if write_complex_part * targhooks.h: Add default_read_complex_part and default_write_complex_part * doc/tm.texi: Document the new TARGET_READ_COMPLEX_PART and TARGET_WRITE_COMPLEX_PART hooks * doc/tm.texi.in: Add TARGET_READ_COMPLEX_PART and TARGET_WRITE_COMPLEX_PART * expr.cc (write_complex_part): Call TARGET_READ_COMPLEX_PART hook (read_complex_part): Call TARGET_WRITE_COMPLEX_PART hook * expr.h: Update function signatures of read_complex_part and write_complex_part * builtins.cc (expand_ifn_atomic_compare_exchange_into_call): Update calls to read_complex_part and write_complex_part (expand_ifn_atomic_compare_exchange): Likewise * expmed.cc (flip_storage_order): Likewise (clear_storage_hints): Likewise and write_complex_part (emit_move_complex_push): Likewise (emit_move_complex_parts): Likewise (expand_assignment): Likewise (expand_expr_real_2): Likewise (expand_expr_real_1): Likewise (const_vector_from_tree): Likewise * internal-fn.cc (expand_arith_set_overflow): Likewise (expand_arith_overflow_result_store): Likewise (expand_addsub_overflow): Likewise (expand_neg_overflow): Likewise (expand_mul_overflow): Likewise (expand_arith_overflow): Likewise (expand_UADDC): Likewise --- gcc/builtins.cc | 8 +-- gcc/doc/tm.texi | 10 +++ gcc/doc/tm.texi.in | 4 ++ gcc/expmed.cc | 4 +- gcc/expr.cc | 164 +++++++++------------------------------------ gcc/expr.h | 5 +- gcc/internal-fn.cc | 20 +++--- gcc/target.def | 18 +++++ gcc/targhooks.cc | 139 ++++++++++++++++++++++++++++++++++++++ gcc/targhooks.h | 5 ++ 10 files changed, 224 insertions(+), 153 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 6dff5214ff8..37da6bcae6f 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -6347,8 +6347,8 @@ expand_ifn_atomic_compare_exchange_into_call (gcall *call, machine_mode mode) if (GET_MODE (boolret) != mode) boolret = convert_modes (mode, GET_MODE (boolret), boolret, 1); x = force_reg (mode, x); - write_complex_part (target, boolret, true, true); - write_complex_part (target, x, false, false); + write_complex_part (target, boolret, IMAG_P, true); + write_complex_part (target, x, REAL_P, false); } } @@ -6403,8 +6403,8 @@ expand_ifn_atomic_compare_exchange (gcall *call) rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); if (GET_MODE (boolret) != mode) boolret = convert_modes (mode, GET_MODE (boolret), boolret, 1); - write_complex_part (target, boolret, true, true); - write_complex_part (target, oldval, false, false); + write_complex_part (target, boolret, IMAG_P, true); + write_complex_part (target, oldval, REAL_P, false); } } diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index 95ba56e05ae..87997b76338 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4605,6 +4605,16 @@ to return a nonzero value when it is required, the compiler will run out of spill registers and print a fatal error message. @end deftypefn +@deftypefn {Target Hook} rtx TARGET_READ_COMPLEX_PART (rtx @var{cplx}, complex_part_t @var{part}) +This hook should return the rtx representing the specified @var{part} of the complex given by @var{cplx}. + @var{part} can be the real part, the imaginary part, or both of them. +@end deftypefn + +@deftypefn {Target Hook} void TARGET_WRITE_COMPLEX_PART (rtx @var{cplx}, rtx @var{val}, complex_part_t @var{part}, bool @var{undefined_p}) +This hook should move the rtx value given by @var{val} to the specified @var{var} of the complex given by @var{cplx}. + @var{var} can be the real part, the imaginary part, or both of them. +@end deftypefn + @node Scalar Return @subsection How Scalar Function Values Are Returned @cindex return values in registers diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 4ac96dc357d..efbf972e6a7 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3390,6 +3390,10 @@ stack. @hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P +@hook TARGET_READ_COMPLEX_PART + +@hook TARGET_WRITE_COMPLEX_PART + @node Scalar Return @subsection How Scalar Function Values Are Returned @cindex return values in registers diff --git a/gcc/expmed.cc b/gcc/expmed.cc index fbd4ce2d42f..2f787cc28f9 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -394,8 +394,8 @@ flip_storage_order (machine_mode mode, rtx x) if (COMPLEX_MODE_P (mode)) { - rtx real = read_complex_part (x, false); - rtx imag = read_complex_part (x, true); + rtx real = read_complex_part (x, REAL_P); + rtx imag = read_complex_part (x, IMAG_P); real = flip_storage_order (GET_MODE_INNER (mode), real); imag = flip_storage_order (GET_MODE_INNER (mode), imag); diff --git a/gcc/expr.cc b/gcc/expr.cc index fff09dc9951..e1a0892b4d9 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -3480,8 +3480,8 @@ clear_storage_hints (rtx object, rtx size, enum block_op_methods method, zero = CONST0_RTX (GET_MODE_INNER (mode)); if (zero != NULL) { - write_complex_part (object, zero, 0, true); - write_complex_part (object, zero, 1, false); + write_complex_part (object, zero, REAL_P, true); + write_complex_part (object, zero, IMAG_P, false); return NULL; } } @@ -3646,126 +3646,18 @@ set_storage_via_setmem (rtx object, rtx size, rtx val, unsigned int align, If UNDEFINED_P then the value in CPLX is currently undefined. */ void -write_complex_part (rtx cplx, rtx val, bool imag_p, bool undefined_p) +write_complex_part (rtx cplx, rtx val, complex_part_t part, bool undefined_p) { - machine_mode cmode; - scalar_mode imode; - unsigned ibitsize; - - if (GET_CODE (cplx) == CONCAT) - { - emit_move_insn (XEXP (cplx, imag_p), val); - return; - } - - cmode = GET_MODE (cplx); - imode = GET_MODE_INNER (cmode); - ibitsize = GET_MODE_BITSIZE (imode); - - /* For MEMs simplify_gen_subreg may generate an invalid new address - because, e.g., the original address is considered mode-dependent - by the target, which restricts simplify_subreg from invoking - adjust_address_nv. Instead of preparing fallback support for an - invalid address, we call adjust_address_nv directly. */ - if (MEM_P (cplx)) - { - emit_move_insn (adjust_address_nv (cplx, imode, - imag_p ? GET_MODE_SIZE (imode) : 0), - val); - return; - } - - /* If the sub-object is at least word sized, then we know that subregging - will work. This special case is important, since store_bit_field - wants to operate on integer modes, and there's rarely an OImode to - correspond to TCmode. */ - if (ibitsize >= BITS_PER_WORD - /* For hard regs we have exact predicates. Assume we can split - the original object if it spans an even number of hard regs. - This special case is important for SCmode on 64-bit platforms - where the natural size of floating-point regs is 32-bit. */ - || (REG_P (cplx) - && REGNO (cplx) < FIRST_PSEUDO_REGISTER - && REG_NREGS (cplx) % 2 == 0)) - { - rtx part = simplify_gen_subreg (imode, cplx, cmode, - imag_p ? GET_MODE_SIZE (imode) : 0); - if (part) - { - emit_move_insn (part, val); - return; - } - else - /* simplify_gen_subreg may fail for sub-word MEMs. */ - gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD); - } - - store_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, 0, 0, imode, val, - false, undefined_p); + targetm.write_complex_part (cplx, val, part, undefined_p); } /* Extract one of the components of the complex value CPLX. Extract the real part if IMAG_P is false, and the imaginary part if it's true. */ rtx -read_complex_part (rtx cplx, bool imag_p) -{ - machine_mode cmode; - scalar_mode imode; - unsigned ibitsize; - - if (GET_CODE (cplx) == CONCAT) - return XEXP (cplx, imag_p); - - cmode = GET_MODE (cplx); - imode = GET_MODE_INNER (cmode); - ibitsize = GET_MODE_BITSIZE (imode); - - /* Special case reads from complex constants that got spilled to memory. */ - if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF) - { - tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0)); - if (decl && TREE_CODE (decl) == COMPLEX_CST) - { - tree part = imag_p ? TREE_IMAGPART (decl) : TREE_REALPART (decl); - if (CONSTANT_CLASS_P (part)) - return expand_expr (part, NULL_RTX, imode, EXPAND_NORMAL); - } - } - - /* For MEMs simplify_gen_subreg may generate an invalid new address - because, e.g., the original address is considered mode-dependent - by the target, which restricts simplify_subreg from invoking - adjust_address_nv. Instead of preparing fallback support for an - invalid address, we call adjust_address_nv directly. */ - if (MEM_P (cplx)) - return adjust_address_nv (cplx, imode, - imag_p ? GET_MODE_SIZE (imode) : 0); - - /* If the sub-object is at least word sized, then we know that subregging - will work. This special case is important, since extract_bit_field - wants to operate on integer modes, and there's rarely an OImode to - correspond to TCmode. */ - if (ibitsize >= BITS_PER_WORD - /* For hard regs we have exact predicates. Assume we can split - the original object if it spans an even number of hard regs. - This special case is important for SCmode on 64-bit platforms - where the natural size of floating-point regs is 32-bit. */ - || (REG_P (cplx) - && REGNO (cplx) < FIRST_PSEUDO_REGISTER - && REG_NREGS (cplx) % 2 == 0)) - { - rtx ret = simplify_gen_subreg (imode, cplx, cmode, - imag_p ? GET_MODE_SIZE (imode) : 0); - if (ret) - return ret; - else - /* simplify_gen_subreg may fail for sub-word MEMs. */ - gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD); - } - - return extract_bit_field (cplx, ibitsize, imag_p ? ibitsize : 0, - true, NULL_RTX, imode, imode, false, NULL); +read_complex_part (rtx cplx, complex_part_t part) +{ + return targetm.read_complex_part (cplx, part); } /* A subroutine of emit_move_insn_1. Yet another lowpart generator. @@ -3936,9 +3828,10 @@ emit_move_complex_push (machine_mode mode, rtx x, rtx y) } emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)), - read_complex_part (y, imag_first)); + read_complex_part (y, (imag_first) ? IMAG_P : REAL_P)); return emit_move_insn (gen_rtx_MEM (submode, XEXP (x, 0)), - read_complex_part (y, !imag_first)); + read_complex_part (y, + (imag_first) ? REAL_P : IMAG_P)); } /* A subroutine of emit_move_complex. Perform the move from Y to X @@ -3954,8 +3847,8 @@ emit_move_complex_parts (rtx x, rtx y) && REG_P (x) && !reg_overlap_mentioned_p (x, y)) emit_clobber (x); - write_complex_part (x, read_complex_part (y, false), false, true); - write_complex_part (x, read_complex_part (y, true), true, false); + write_complex_part (x, read_complex_part (y, REAL_P), REAL_P, true); + write_complex_part (x, read_complex_part (y, IMAG_P), IMAG_P, false); return get_last_insn (); } @@ -5812,9 +5705,9 @@ expand_assignment (tree to, tree from, bool nontemporal) if (from_rtx) { emit_move_insn (XEXP (to_rtx, 0), - read_complex_part (from_rtx, false)); + read_complex_part (from_rtx, REAL_P)); emit_move_insn (XEXP (to_rtx, 1), - read_complex_part (from_rtx, true)); + read_complex_part (from_rtx, IMAG_P)); } else { @@ -5836,14 +5729,16 @@ expand_assignment (tree to, tree from, bool nontemporal) concat_store_slow:; rtx temp = assign_stack_temp (GET_MODE (to_rtx), GET_MODE_SIZE (GET_MODE (to_rtx))); - write_complex_part (temp, XEXP (to_rtx, 0), false, true); - write_complex_part (temp, XEXP (to_rtx, 1), true, false); + write_complex_part (temp, XEXP (to_rtx, 0), REAL_P, true); + write_complex_part (temp, XEXP (to_rtx, 1), IMAG_P, false); result = store_field (temp, bitsize, bitpos, bitregion_start, bitregion_end, mode1, from, get_alias_set (to), nontemporal, reversep); - emit_move_insn (XEXP (to_rtx, 0), read_complex_part (temp, false)); - emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true)); + emit_move_insn (XEXP (to_rtx, 0), + read_complex_part (temp, REAL_P)); + emit_move_insn (XEXP (to_rtx, 1), + read_complex_part (temp, IMAG_P)); } } /* For calls to functions returning variable length structures, if TO_RTX @@ -10322,8 +10217,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, complex_expr_swap_order: /* Move the imaginary (op1) and real (op0) parts to their location. */ - write_complex_part (target, op1, true, true); - write_complex_part (target, op0, false, false); + write_complex_part (target, op1, IMAG_P, true); + write_complex_part (target, op0, REAL_P, false); return target; } @@ -10352,8 +10247,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, } /* Move the real (op0) and imaginary (op1) parts to their location. */ - write_complex_part (target, op0, false, true); - write_complex_part (target, op1, true, false); + write_complex_part (target, op0, REAL_P, true); + write_complex_part (target, op1, IMAG_P, false); return target; @@ -11508,7 +11403,8 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, rtx parts[2]; for (int i = 0; i < 2; i++) { - rtx op = read_complex_part (op0, i != 0); + rtx op = + read_complex_part (op0, (i != 0) ? IMAG_P : REAL_P); if (GET_CODE (op) == SUBREG) op = force_reg (GET_MODE (op), op); temp = gen_lowpart_common (GET_MODE_INNER (mode1), op); @@ -12106,11 +12002,11 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode, case REALPART_EXPR: op0 = expand_normal (treeop0); - return read_complex_part (op0, false); + return read_complex_part (op0, REAL_P); case IMAGPART_EXPR: op0 = expand_normal (treeop0); - return read_complex_part (op0, true); + return read_complex_part (op0, IMAG_P); case RETURN_EXPR: case LABEL_EXPR: @@ -13449,8 +13345,8 @@ const_vector_from_tree (tree exp) builder.quick_push (const_double_from_real_value (TREE_REAL_CST (elt), inner)); else if (TREE_CODE (elt) == FIXED_CST) - builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE (TREE_FIXED_CST (elt), - inner)); + builder.quick_push (CONST_FIXED_FROM_FIXED_VALUE + (TREE_FIXED_CST (elt), inner)); else builder.quick_push (immed_wide_int_const (wi::to_poly_wide (elt), inner)); diff --git a/gcc/expr.h b/gcc/expr.h index 11bff531862..833ff16bd0d 100644 --- a/gcc/expr.h +++ b/gcc/expr.h @@ -261,9 +261,8 @@ extern rtx_insn *emit_move_insn_1 (rtx, rtx); extern rtx_insn *emit_move_complex_push (machine_mode, rtx, rtx); extern rtx_insn *emit_move_complex_parts (rtx, rtx); -extern rtx read_complex_part (rtx, bool); -extern void write_complex_part (rtx, rtx, bool, bool); -extern rtx read_complex_part (rtx, bool); +extern rtx read_complex_part (rtx, complex_part_t); +extern void write_complex_part (rtx, rtx, complex_part_t, bool); extern rtx emit_move_resolve_push (machine_mode, rtx); /* Push a block of length SIZE (perhaps variable) diff --git a/gcc/internal-fn.cc b/gcc/internal-fn.cc index f9aaf66cf2a..8d3d4599256 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -917,9 +917,9 @@ expand_arith_set_overflow (tree lhs, rtx target) { if (TYPE_PRECISION (TREE_TYPE (TREE_TYPE (lhs))) == 1 && !TYPE_UNSIGNED (TREE_TYPE (TREE_TYPE (lhs)))) - write_complex_part (target, constm1_rtx, true, false); + write_complex_part (target, constm1_rtx, IMAG_P, false); else - write_complex_part (target, const1_rtx, true, false); + write_complex_part (target, const1_rtx, IMAG_P, false); } /* Helper for expand_*_overflow. Store RES into the __real__ part @@ -974,7 +974,7 @@ expand_arith_overflow_result_store (tree lhs, rtx target, expand_arith_set_overflow (lhs, target); emit_label (done_label); } - write_complex_part (target, lres, false, false); + write_complex_part (target, lres, REAL_P, false); } /* Helper for expand_*_overflow. Store RES into TARGET. */ @@ -1019,7 +1019,7 @@ expand_addsub_overflow (location_t loc, tree_code code, tree lhs, { target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); if (!is_ubsan) - write_complex_part (target, const0_rtx, true, false); + write_complex_part (target, const0_rtx, IMAG_P, false); } /* We assume both operands and result have the same precision @@ -1464,7 +1464,7 @@ expand_neg_overflow (location_t loc, tree lhs, tree arg1, bool is_ubsan, { target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); if (!is_ubsan) - write_complex_part (target, const0_rtx, true, false); + write_complex_part (target, const0_rtx, IMAG_P, false); } enum insn_code icode = optab_handler (negv3_optab, mode); @@ -1589,7 +1589,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1, { target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); if (!is_ubsan) - write_complex_part (target, const0_rtx, true, false); + write_complex_part (target, const0_rtx, IMAG_P, false); } if (is_ubsan) @@ -2406,7 +2406,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0, tree arg1, do_compare_rtx_and_jump (op1, res, NE, true, mode, NULL_RTX, NULL, all_done_label, profile_probability::very_unlikely ()); emit_label (set_noovf); - write_complex_part (target, const0_rtx, true, false); + write_complex_part (target, const0_rtx, IMAG_P, false); emit_label (all_done_label); } @@ -2675,7 +2675,7 @@ expand_arith_overflow (enum tree_code code, gimple *stmt) { /* The infinity precision result will always fit into result. */ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE); - write_complex_part (target, const0_rtx, true, false); + write_complex_part (target, const0_rtx, IMAG_P, false); scalar_int_mode mode = SCALAR_INT_TYPE_MODE (type); struct separate_ops ops; ops.code = code; @@ -2840,8 +2840,8 @@ expand_UADDC (internal_fn ifn, gcall *stmt) create_input_operand (&ops[3], op2, mode); create_input_operand (&ops[4], op3, mode); expand_insn (icode, 5, ops); - write_complex_part (target, re, false, false); - write_complex_part (target, im, true, false); + write_complex_part (target, re, REAL_P, false); + write_complex_part (target, im, IMAG_P, false); } /* Expand USUBC STMT. */ diff --git a/gcc/target.def b/gcc/target.def index 7d684296c17..9798c0f58e4 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3306,6 +3306,24 @@ a pointer to int.", bool, (ao_ref *ref), default_ref_may_alias_errno) +/* Returns the value corresponding to the specified part of a complex. */ +DEFHOOK +(read_complex_part, + "This hook should return the rtx representing the specified @var{part} of the complex given by @var{cplx}.\n\ + @var{part} can be the real part, the imaginary part, or both of them.", + rtx, + (rtx cplx, complex_part_t part), + default_read_complex_part) + +/* Moves a value to the specified part of a complex */ +DEFHOOK +(write_complex_part, + "This hook should move the rtx value given by @var{val} to the specified @var{var} of the complex given by @var{cplx}.\n\ + @var{var} can be the real part, the imaginary part, or both of them.", + void, + (rtx cplx, rtx val, complex_part_t part, bool undefined_p), + default_write_complex_part) + /* Support for named address spaces. */ #undef HOOK_PREFIX #define HOOK_PREFIX "TARGET_ADDR_SPACE_" diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc index e190369f87a..d33fcbd9a13 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -1532,6 +1532,145 @@ default_preferred_simd_mode (scalar_mode) return word_mode; } +/* By default, extract one of the components of the complex value CPLX. Extract the + real part if part is REAL_P, and the imaginary part if it is IMAG_P. If part is + BOTH_P, return cplx directly*/ + +rtx +default_read_complex_part (rtx cplx, complex_part_t part) +{ + machine_mode cmode; + scalar_mode imode; + unsigned ibitsize; + + if (part == BOTH_P) + return cplx; + + if (GET_CODE (cplx) == CONCAT) + return XEXP (cplx, part); + + cmode = GET_MODE (cplx); + imode = GET_MODE_INNER (cmode); + ibitsize = GET_MODE_BITSIZE (imode); + + /* Special case reads from complex constants that got spilled to memory. */ + if (MEM_P (cplx) && GET_CODE (XEXP (cplx, 0)) == SYMBOL_REF) + { + tree decl = SYMBOL_REF_DECL (XEXP (cplx, 0)); + if (decl && TREE_CODE (decl) == COMPLEX_CST) + { + tree cplx_part = + (part == IMAG_P) ? TREE_IMAGPART (decl) : TREE_REALPART (decl); + if (CONSTANT_CLASS_P (cplx_part)) + return expand_expr (cplx_part, NULL_RTX, imode, EXPAND_NORMAL); + } + } + + /* For MEMs simplify_gen_subreg may generate an invalid new address + because, e.g., the original address is considered mode-dependent + by the target, which restricts simplify_subreg from invoking + adjust_address_nv. Instead of preparing fallback support for an + invalid address, we call adjust_address_nv directly. */ + if (MEM_P (cplx)) + return adjust_address_nv (cplx, imode, (part == IMAG_P) + ? GET_MODE_SIZE (imode) : 0); + + /* If the sub-object is at least word sized, then we know that subregging + will work. This special case is important, since extract_bit_field + wants to operate on integer modes, and there's rarely an OImode to + correspond to TCmode. */ + if (ibitsize >= BITS_PER_WORD + /* For hard regs we have exact predicates. Assume we can split + the original object if it spans an even number of hard regs. + This special case is important for SCmode on 64-bit platforms + where the natural size of floating-point regs is 32-bit. */ + || (REG_P (cplx) + && REGNO (cplx) < FIRST_PSEUDO_REGISTER + && REG_NREGS (cplx) % 2 == 0)) + { + rtx ret = simplify_gen_subreg (imode, cplx, cmode, (part == IMAG_P) + ? GET_MODE_SIZE (imode) : 0); + if (ret) + return ret; + else + /* simplify_gen_subreg may fail for sub-word MEMs. */ + gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD); + } + + return extract_bit_field (cplx, ibitsize, (part == IMAG_P) ? ibitsize : 0, + true, NULL_RTX, imode, imode, false, NULL); +} + +/* By default, Write to one of the components of the complex value CPLX. Write VAL to + the real part if part is REAL_P, and the imaginary part if it is IMAG_P. If part is + BOTH_P, call recursively with REAL_P and IMAG_P */ + +void +default_write_complex_part (rtx cplx, rtx val, complex_part_t part, bool undefined_p) +{ + machine_mode cmode; + scalar_mode imode; + unsigned ibitsize; + + if (part == BOTH_P) + { + write_complex_part (cplx, read_complex_part (val, REAL_P), REAL_P, false); + write_complex_part (cplx, read_complex_part (val, IMAG_P), IMAG_P, false); + return; + } + + if (GET_CODE (cplx) == CONCAT) + { + emit_move_insn (XEXP (cplx, part == IMAG_P), val); + return; + } + + cmode = GET_MODE (cplx); + imode = GET_MODE_INNER (cmode); + ibitsize = GET_MODE_BITSIZE (imode); + + /* For MEMs simplify_gen_subreg may generate an invalid new address + because, e.g., the original address is considered mode-dependent + by the target, which restricts simplify_subreg from invoking + adjust_address_nv. Instead of preparing fallback support for an + invalid address, we call adjust_address_nv directly. */ + if (MEM_P (cplx)) + { + emit_move_insn (adjust_address_nv (cplx, imode, (part == IMAG_P) + ? GET_MODE_SIZE (imode) : 0), val); + return; + } + + /* If the sub-object is at least word sized, then we know that subregging + will work. This special case is important, since store_bit_field + wants to operate on integer modes, and there's rarely an OImode to + correspond to TCmode. */ + if (ibitsize >= BITS_PER_WORD + /* For hard regs we have exact predicates. Assume we can split + the original object if it spans an even number of hard regs. + This special case is important for SCmode on 64-bit platforms + where the natural size of floating-point regs is 32-bit. */ + || (REG_P (cplx) + && REGNO (cplx) < FIRST_PSEUDO_REGISTER + && REG_NREGS (cplx) % 2 == 0)) + { + rtx cplx_part = simplify_gen_subreg (imode, cplx, cmode, + (part == IMAG_P) ? + GET_MODE_SIZE (imode) : 0); + if (cplx_part) + { + emit_move_insn (cplx_part, val); + return; + } + else + /* simplify_gen_subreg may fail for sub-word MEMs. */ + gcc_assert (MEM_P (cplx) && ibitsize < BITS_PER_WORD); + } + + store_bit_field (cplx, ibitsize, (part == IMAG_P) ? ibitsize : 0, 0, 0, + imode, val, false, undefined_p); +} + /* By default do not split reductions further. */ machine_mode diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 1a0db8dddd5..805abd96938 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -124,6 +124,11 @@ extern opt_machine_mode default_get_mask_mode (machine_mode); extern bool default_empty_mask_is_expensive (unsigned); extern vector_costs *default_vectorize_create_costs (vec_info *, bool); +extern rtx default_read_complex_part (rtx cplx, complex_part_t part); +extern void default_write_complex_part (rtx cplx, rtx val, + complex_part_t part, + bool undefined_p); + /* OpenACC hooks. */ extern bool default_goacc_validate_dims (tree, int [], int, unsigned); extern int default_goacc_dim_limit (int); -- 2.17.1