From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mxout.security-mail.net (mxout.security-mail.net [85.31.212.43]) by sourceware.org (Postfix) with ESMTPS id 11C643858430 for ; Tue, 12 Sep 2023 10:07:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 11C643858430 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 (fx303.security-mail.net [127.0.0.1]) by fx303.security-mail.net (Postfix) with ESMTP id BBA9F30EB22 for ; Tue, 12 Sep 2023 12:07:32 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kalrayinc.com; s=sec-sig-email; t=1694513252; bh=x6gZgPxEuvShs3rtxyRWTUWomtWPYwtb+rj6iXejK1w=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=cDKotYNxY9iucQbFJmQUOGeSPOO+JPOghKDM4OpfqIynVzkVb48s8t2q0ez+p27C2 ETNsKPnz5Pn31BL2NVN8DXwM9sOUNrUB+JHfFIsBqdoe27arsMPFlAJG+VTdQP4I4C 0txAnP1AmUYE04x5sOT2CdQY30osEEllK4iB+Pq0= Received: from fx303 (fx303.security-mail.net [127.0.0.1]) by fx303.security-mail.net (Postfix) with ESMTP id 9F49D30EABA for ; Tue, 12 Sep 2023 12:07:32 +0200 (CEST) Received: from FRA01-MR2-obe.outbound.protection.outlook.com (mail-mr2fra01on0103.outbound.protection.outlook.com [104.47.25.103]) by fx303.security-mail.net (Postfix) with ESMTPS id F260630E962 for ; Tue, 12 Sep 2023 12:07:31 +0200 (CEST) Received: from PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:184::6) by MRZP264MB2442.FRAP264.PROD.OUTLOOK.COM (2603:10a6:501:7::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6768.35; Tue, 12 Sep 2023 10:07:29 +0000 Received: from PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM ([fe80::ad9:f173:8a66:3461]) by PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM ([fe80::ad9:f173:8a66:3461%7]) with mapi id 15.20.6768.029; Tue, 12 Sep 2023 10:07:29 +0000 X-Virus-Scanned: E-securemail Secumail-id: <40f.65003863.f1a89.0> ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Mlbuvnv7ktBG1gEYjfXIBIE0VpAZjH+agLRVXjL5TT3MYahytUJ1I8GmmdHO/vUHZ/xI1Cb3IPnciAusvF4+++kTcmAqg9OopsUAgHfVGeoQ0i6eopSXJ4e3j9GeJOmRUH3aehkqXWbKEr3V9njfGjaYd56pjnYNo32sv3X9IU5+fZ88iIgm+EqfjaLiRgl9zfV6ThOxsLtRDE+kXyILKOacd4eZ+NRwT9ZwprSx1Y7IQ82Mtg8lqnmGx6VaWdt36uRS3uXDilFNKs5iwsAdSY5Lx0vjbqwjDW1YKvhww6QIpyK1sc6XSrkfY7yqYDfzjGfFoL5jDBN3qSYfyl0aug== 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=9CXCXrcPQJfHDwMvtxWpgG93j0KCM4LWXA61OMyjQp4=; b=XVakDSwn5brnEf8fYpm4xLPtxXQ4tLuyOZA0DHzt1sPhLUzNZnWJanGiyq/p82CVqWNcguzdTN9XZKu8Dl9XzXV4Y1k+yzsqOGLJygvT0LVxyKrfv0jcdf4roJYG104EXAhcdg6iuzg2i7pkQglDZEI9dpshcpkxs+ib2muD9S1+7Mkv4ln6CP8hCITIkyajcsipmq0Ty8ISaWIeI7rZIQrVfCFfUr3lzryBMR9fpGgDqyYciwTNI4hwhfx1AZ2mRqCi2OdFthA4QD/8bdhZB/cuGeXXhg/h1pPEoQ7PR9EmdvdsqzYbZXDxB4+RhCoNe1MB8a83iQBeZhCHQehkrg== 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=9CXCXrcPQJfHDwMvtxWpgG93j0KCM4LWXA61OMyjQp4=; b=G7rH0alP/2G/2PJpJxYSEWu1frgwrxS3uYvFWJ5mvcNn5Wxd8CcEyZMyeeZIU2J46+mAHEkJlXiCGUHpUM5ruO9pFQSvaLUVrgClPxYv5C1Ner1aRH08dChpL5yP4UfKtixwyYksqCWStmI6IkveCanjQjgicg4OOfYsnEnzumHn6nsxLhYLER0sD5nJNbvmjF378OVxl+/0l5QFbJQXgHk7v/gls7MUGHsBIewZfUqP/jKdJ88cYVwhLc3EJDaH2Xa+Fm220oDex6EpQDsSwmB/vVfxh0FguG8RqHFOPQYcknmVFqvfXCEJNF1Xx+j6fqJ/qv+OG3IHCpAs9EH1GA== 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 v2 02/11] Native complex ops: Move functions to hooks Date: Tue, 12 Sep 2023 12:07:04 +0200 Message-ID: <20230912100713.1074-3-snoiry@kalrayinc.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20230912100713.1074-1-snoiry@kalrayinc.com> References: <20230717090250.4645-10-snoiry@kalrayinc.com> <20230912100713.1074-1-snoiry@kalrayinc.com> X-ClientProxiedBy: LNXP123CA0003.GBRP123.PROD.OUTLOOK.COM (2603:10a6:600:d2::15) To PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM (2603:10a6:102:184::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PR1P264MB3448:EE_|MRZP264MB2442:EE_ X-MS-Office365-Filtering-Correlation-Id: 3056cd43-b66c-4427-70c5-08dbb37812cc X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: FlBWMCk4Ioo4s6vtnF9Y/HgCQH03E4+K2tFWw9+kWYoAVmlWS1SWdIfkuKDbrXpyl9vhTB7ZKCRh9DMcYEP7G2qX9vX3vpVq9iZYuicKatmEXGuJriFSwL3L+UMgZwQ74iZGip8EjXil06wWdwVvqRhsZtR1c4aWE3qB6nHYpJKdO4wIok8MTKFMcsBdHYjTeAZ2BJOn0ttPJ9gISM0wwMBOjXr7n1My2+WBg0b5Z3tlwE7W7UsXzH68KLbyG5czEtQh5AZaVraKtj9AobIKosdHNvrNe4v1D/EuXGGCc1oPo4mkYcIXqCgidEwY/QbU5JN4ffURUeroD6i6/3vowqlYqh9EXemH277h5urRGNKgfjlKVwSmLQ8C7av+8Bv3Q9WpPh4z+6qbrKXpemy5X62vKDse3lK/9zy2SSpcKakWTayElyghFbVXk+CEGLcUx/gINEgh98ffUSz2nOWx8GL4Kk3hahrgGuVZG+h+HGJDNLTDcr9TdlWdLWnluxNtxQRc6u2T1msF1ER9U2kuGpsKGBdQ3yXExI5aS9iIq/7Oo/oUn1cm5CB+7+T8Gfgy X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM;PTR:;CAT:NONE;SFS:(13230031)(136003)(366004)(376002)(346002)(396003)(39860400002)(451199024)(186009)(1800799009)(1076003)(107886003)(2616005)(5660300002)(4326008)(8936002)(8676002)(6512007)(26005)(6486002)(6666004)(6506007)(83380400001)(66476007)(66556008)(66946007)(38100700002)(478600001)(41300700001)(6916009)(316002)(36756003)(86362001)(30864003)(2906002);DIR:OUT;SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: IWL4CD2/xln9AQvUlAeojmd3ZdB6/N+EepDEqnLBIJyFf2a8ba1eXkBJOVwQeyp9axIB2Xe8BfjkpH5+16Ia9XfEqU87otOlFBwHnQtHNHPmTRFMpKNpGxEQhT03qoh1Mmsa4QBHT8O4TNUqs/b5NQArszy5cVNlbLquDa4EaRl9fmrIrlx8zMGH9wIQfA214e3ZtqPcy8gfOYaUYwAUZPlDUTOM8eL44/A8aK56jPJFWlGpnjwSy0csd8pMxUI1dX8UkoQyvsvB2OI9lwz04IGUnx6ynEkIqNeOV6ehXJRrrhkuR4B0BFly+Xv+egoCVy58UkLrkdTzAKGR8gpzCQGJfy/NHaToP0j7R/hMJv3w6ol4U9uiRawL2qOqvWaI6T3I+OwSKH05/uYcnnvRCVFdcP30FateKJ5WT0QlSv+44xBgDpoSGgKMjwG5tgWdNvnFnBl+Ehch3NWkqt8837Q0KoAJxU0tgIwJfHGTvMVdqeYattEY1ny9K+mPd6pUr/QJFURF4MizClmLp4WXhurMoHW47ofCjNwGaQ2A3WERAL+Wu4ntTCgDDzqKnYnHh5wSZBXMUB3X6ygD5gliOfJFEvIPpmzOt8vTTF9C6RfWjP4zWO2IWw5p+rXHvFUJq4QiIxWYaqOYOBQCJryTDI0a0zkZHJpa8ly/DIzPJV+3o37NZHp5M8ES8qK8mZ1/XoUwWjZSVhiRCE6bmBqMaR1zhXuEb1x+amObkK2dyJh/ISXgI0CIk4r15XEq7lxClFeQQ8xyJEp/3qbzZpcX5GZVZHDNr47dg9+kWQW3gd4+JW4e7CLoBWJW2KTGmwcL3gDd0EW2FYxldi3ejVBdoiOHtRNZQS7i413Btr+7scmMOf70QcSvSQ58UdkRPFSRNKCBiT0howvTFrw5VgHrjOh37JI4JvVJoTQ3sAtg9UMfF0Wc69N9ld170yJb/J9G 9P5CCpAugfkgGNT0SUDcggZ5+ob3EiqS3Vks+rJ4dOYo8+I2VEJiGSEPKFENBsrVqDGnp+UWld7rwY8Xeqtqwab8jEwhsAlbIUDPuAAM/vxUxIbT7id+xv3tdrLcrVV77aqTbiAoyMoKmNjlG8qBOK5YgAS1CNZ1Sg3gR035d08XUuwRgKX2YYUT9UG76jdszQgl0p8BfiUw/lAOJTbiOt4Jv1X1N0XpSFl5i4Zx1zDUmJenDPPDcPDS2wyKudbvlSHBXumGfgOiLMNu3bIjaRVIY0CDhPKIjQJZzETmij7fgzubATu2xX7/3e1N/MrzdjJ9DhCDmvsedLANo4qkqO6/gLq9vYqvFEIALV25JbWVmci3adXbbsdl/fZLw7r5gUkudlt2kAKO1uRHc0SDh+D4ASR1pruU0XZo3lK1U0DqHIs8+v1v3GLVJxXzRcciKpRFP7N7sicuvQsWhCAQg9WN0iiAel73Ma6Gq2dqzdJux/g0EYl0S+nEx8yTY0/yO2dZiWkuW1s6MqCcLABkGiIolLI2ifr7f6Of0yQKraPh6QvzR2e/AE91XvSBjhW/WnO4UN6KpI/a91bQ45Bcrx6uDOtkDClo64LRiOIe38bVMAhJYFzP58qodaTk1tpFwjvWtbn9j4f444u3vm/YwA== X-OriginatorOrg: kalrayinc.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3056cd43-b66c-4427-70c5-08dbb37812cc X-MS-Exchange-CrossTenant-AuthSource: PR1P264MB3448.FRAP264.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 12 Sep 2023 10:07:29.6972 (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: 4nkEwytA/hOAe2Y9Mipuy1tdjUCafc44h6w+Vk8sW+XLyMgJX4P9GkMvZZBoxXfjQgWIJJFvcJmE8tgtjU5vYw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MRZP264MB2442 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-ALTERMIMEV2_out: done X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,KAM_STOCKGEN,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: Summary: 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 | 165 +++++++++------------------------------------ gcc/expr.h | 5 +- gcc/internal-fn.cc | 16 ++--- gcc/target.def | 18 +++++ gcc/targhooks.cc | 139 ++++++++++++++++++++++++++++++++++++++ gcc/targhooks.h | 4 ++ 10 files changed, 221 insertions(+), 152 deletions(-) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index 3b453b3ec8c..b5cb652c413 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -6349,8 +6349,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); } } @@ -6405,8 +6405,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 ff69207fb9f..c4f935b5746 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -4620,6 +4620,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}) +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 cad6308a87c..b8970761c8d 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3392,6 +3392,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 b294eabb08d..973c16a14d3 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 d5b6494b4fc..12b74273144 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -3475,8 +3475,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; } } @@ -3641,126 +3641,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. @@ -3931,9 +3823,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 @@ -3949,8 +3842,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 (); } @@ -5807,9 +5700,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 { @@ -5831,14 +5724,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 @@ -10317,8 +10212,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; } @@ -10346,9 +10241,8 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode, break; } - /* 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); + /* Temporary use a CONCAT to pass both real and imag parts in one call. */ + write_complex_part (target, gen_rtx_CONCAT (GET_MODE (target), op0, op1), BOTH_P, true); return target; @@ -11550,7 +11444,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); @@ -12150,11 +12045,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: @@ -13494,8 +13389,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 0fd34359247..a01b7160303 100644 --- a/gcc/internal-fn.cc +++ b/gcc/internal-fn.cc @@ -919,9 +919,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 @@ -976,7 +976,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. */ @@ -1051,7 +1051,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 @@ -1496,7 +1496,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); @@ -1621,7 +1621,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) @@ -2444,7 +2444,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); } @@ -2713,7 +2713,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; diff --git a/gcc/target.def b/gcc/target.def index 42622177ef9..f99df939776 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3313,6 +3313,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), + 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 4f5b240f8d6..df852eb18e3 100644 --- a/gcc/targhooks.cc +++ b/gcc/targhooks.cc @@ -1533,6 +1533,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) +{ + machine_mode cmode; + scalar_mode imode; + unsigned ibitsize; + + if (part == BOTH_P) + { + write_complex_part (cplx, read_complex_part (val, REAL_P), REAL_P); + write_complex_part (cplx, read_complex_part (val, IMAG_P), IMAG_P); + 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); +} + /* By default do not split reductions further. */ machine_mode diff --git a/gcc/targhooks.h b/gcc/targhooks.h index 189549cb1c7..dcacc725e27 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -124,6 +124,10 @@ 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); + /* OpenACC hooks. */ extern bool default_goacc_validate_dims (tree, int [], int, unsigned); extern int default_goacc_dim_limit (int); -- 2.17.1