From patchwork Fri Jul 26 18:05:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mariam Arutunian X-Patchwork-Id: 1965381 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=gkDNxuUB; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; 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 [IPv6:2620:52:3:1:0:246e:9693:128c]) (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 4WVwhB4psdz1yXx for ; Sat, 27 Jul 2024 04:07:22 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 65759385841C for ; Fri, 26 Jul 2024 18:07:20 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by sourceware.org (Postfix) with ESMTPS id 5D9DE3858431 for ; Fri, 26 Jul 2024 18:06:05 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5D9DE3858431 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 5D9DE3858431 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::232 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722017171; cv=none; b=f/Lc6Yygf+BqVU9RS2xoOCVyEAxcfGwRjE2P1OXP9DGxDwVrp0otz4shHhc6KRTBnLNNK5pCKsALQGWIUkBkXyamn9wmL4+5BM32A8+jE5Zo1XwD5Gy0NUvFlUfVOGWK+bRJH/jiNkeYygKcJ6mXsCLpHAnWULDIUk4WZmU54X8= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1722017171; c=relaxed/simple; bh=rimWnSbe/oLSZmPiT6I8odQPm9/A04kLCyTRP6PvrO8=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=GmCB22HhVFPFqSK8r46thWzagq6OQKzSCtXHMIxd+dRrdBvjnCwRpVkAOqpgIaa1BZR3aAhHR5nTRBsj6q6U8ZAtE1/q05OTTIBiaNYOcGP7yRhfcdkh/EDi9qfja0Xes5Fyf320CfuFp3xP7kcpr5elfj0Fb6P3WKtahqMi/OI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lj1-x232.google.com with SMTP id 38308e7fff4ca-2f029e9c9cfso24003921fa.2 for ; Fri, 26 Jul 2024 11:06:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722017163; x=1722621963; darn=gcc.gnu.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=I34c+6IY1goIL4ZEtOg8fyk5RYlzcB6GKeYEZ3C/j5s=; b=gkDNxuUBqAvgUSgc/pyG0nbcjG1qr9lTa84/K7qa2V4+9nhIV823X6VRLgFdvbB859 j/K0jAxo9pMI64zsL3hzaTWAuaI7BXBoX3j3QjtJWIX1n6Jp7D+jYiqfPf6KTVkvQejW jJOJcy38DHEjNdOZdQe6P73TjpD4KBAg9BUEhmaAtQZyUC6sLXJ/4j12iAdwbwy9L/Zh oQsTwhtyOKeHHIWkUVmznTpYDMRbf7+R7Ge5LidsJb83AwPqf0NU5VlY+AwwrBp3/W3u sSfOKEwE/n5Xzz+POB8FYF4xyBhlYARZ/J19jDLagivWogva8Ed7/09juMjXzWjOVuCI fMxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722017164; x=1722621964; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=I34c+6IY1goIL4ZEtOg8fyk5RYlzcB6GKeYEZ3C/j5s=; b=XT94aPKanYg0uih/ixnR0aEvOm9o7Gh1gV/lenM71XK8Zvyi7TzKGKHPBb+7+I+ZBN R1HRAgpYnqaH+dgHrA0zxL+vKkOXXRDD8NSKpV1+PzmrP8YE1m1GX4HMViuTdLvUHAuz rlA/FNGppcAiwncWkXjJv90iTIaeszTfiDUJGSEygHFr4NlWZg03/aJ6zoKmvfFk0X66 AdsfrVNayEKBIpsgccMkohVD3MKvnD1HAiZK5RkvulUs8P+ZjABY7rFDdRls8tH5/sw/ sU5kJQh4qUQeoE3faJ6gTfQ6JYqoKWeAwJR/wPNwm+v2fF2/raxNKDMdxR2cAvfzrmGI 6pCg== X-Gm-Message-State: AOJu0YzbEnrkHV/wQ4H9jsxgTAcMoirMUWMyaXfspmL1XGyTDZoqPk6X A0hNSZkzlmBt9zR6txzaF8AzD7lKYv7XfHH30Y/K+s2q/nxZo/0b/arBUWc3FfZkjp01Tt9x1CF 0dIK/3KLDOImRKmFIjVS+pCafMtv7JWCv X-Google-Smtp-Source: AGHT+IFPdMQ5ydQJF5qZKgq/I05l2lmteXLekRPU/ptO+noSTCDihYv/aEoZ47fRkWET9Bf851JEXeVr189JQbSSW7o= X-Received: by 2002:a2e:8717:0:b0:2ef:22a6:d90d with SMTP id 38308e7fff4ca-2f12ee634c6mr3274471fa.47.1722017163405; Fri, 26 Jul 2024 11:06:03 -0700 (PDT) MIME-Version: 1.0 From: Mariam Arutunian Date: Fri, 26 Jul 2024 22:05:49 +0400 Message-ID: Subject: [RFC/RFA][PATCH v2 02/12] Add built-ins and tests for bit-forward and bit-reversed CRCs To: GCC Patches X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, HTML_MESSAGE, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.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 This patch introduces new built-in functions to GCC for computing bit-forward and bit-reversed CRCs. These builtins aim to provide efficient CRC calculation capabilities. When the target architecture supports CRC operations (as indicated by the presence of a CRC optab), the builtins will utilize the expander to generate CRC code. In the absence of hardware support, the builtins default to generating code for a table-based CRC calculation. The built-ins are defined as follows: __builtin_rev_crc16_data8, __builtin_rev_crc32_data8, __builtin_rev_crc32_data16, __builtin_rev_crc32_data32 __builtin_rev_crc64_data8, __builtin_rev_crc64_data16, __builtin_rev_crc64_data32, __builtin_rev_crc64_data64, __builtin_crc8_data8, __builtin_crc16_data16, __builtin_crc16_data8, __builtin_crc32_data8, __builtin_crc32_data16, __builtin_crc32_data32, __builtin_crc64_data8, __builtin_crc64_data16, __builtin_crc64_data32, __builtin_crc64_data64 Each built-in takes three parameters: crc: The initial CRC value. data: The data to be processed. polynomial: The CRC polynomial without the leading 1. To validate the correctness of these built-ins, this patch also includes additions to the GCC testsuite. This enhancement allows GCC to offer developers high-performance CRC computation options that automatically adapt to the capabilities of the target hardware. Co-authored-by: Joern Rennecke Not complete. May continue the work if these built-ins are needed. gcc/ * builtin-types.def (BT_FN_UINT8_UINT8_UINT8_CONST_SIZE): Define. (BT_FN_UINT16_UINT16_UINT8_CONST_SIZE): Likewise. (BT_FN_UINT16_UINT16_UINT16_CONST_SIZE): Likewise. (BT_FN_UINT32_UINT32_UINT8_CONST_SIZE): Likewise. (BT_FN_UINT32_UINT32_UINT16_CONST_SIZE): Likewise. (BT_FN_UINT32_UINT32_UINT32_CONST_SIZE): Likewise. (BT_FN_UINT64_UINT64_UINT8_CONST_SIZE): Likewise. (BT_FN_UINT64_UINT64_UINT16_CONST_SIZE): Likewise. (BT_FN_UINT64_UINT64_UINT32_CONST_SIZE): Likewise. (BT_FN_UINT64_UINT64_UINT64_CONST_SIZE): Likewise. * builtins.cc (associated_internal_fn): Handle BUILT_IN_CRC8_DATA8, BUILT_IN_CRC16_DATA8, BUILT_IN_CRC16_DATA16, BUILT_IN_CRC32_DATA8, BUILT_IN_CRC32_DATA16, BUILT_IN_CRC32_DATA32, BUILT_IN_CRC64_DATA8, BUILT_IN_CRC64_DATA16, BUILT_IN_CRC64_DATA32, BUILT_IN_CRC64_DATA64, BUILT_IN_REV_CRC8_DATA8, BUILT_IN_REV_CRC16_DATA8, BUILT_IN_REV_CRC16_DATA16, BUILT_IN_REV_CRC32_DATA8, BUILT_IN_REV_CRC32_DATA16, BUILT_IN_REV_CRC32_DATA32. (expand_builtin_crc_table_based): New function. (expand_builtin): Handle BUILT_IN_CRC8_DATA8, BUILT_IN_CRC16_DATA8, BUILT_IN_CRC16_DATA16, BUILT_IN_CRC32_DATA8, BUILT_IN_CRC32_DATA16, BUILT_IN_CRC32_DATA32, BUILT_IN_CRC64_DATA8, BUILT_IN_CRC64_DATA16, BUILT_IN_CRC64_DATA32, BUILT_IN_CRC64_DATA64, BUILT_IN_REV_CRC8_DATA8, BUILT_IN_REV_CRC16_DATA8, BUILT_IN_REV_CRC16_DATA16, BUILT_IN_REV_CRC32_DATA8, BUILT_IN_REV_CRC32_DATA16, BUILT_IN_REV_CRC32_DATA32, BUILT_IN_REV_CRC64_DATA8, BUILT_IN_REV_CRC64_DATA16, BUILT_IN_REV_CRC64_DATA32, BUILT_IN_REV_CRC64_DATA64. * builtins.def (BUILT_IN_CRC8_DATA8): New builtin. (BUILT_IN_CRC16_DATA8): Likewise. (BUILT_IN_CRC16_DATA16): Likewise. (BUILT_IN_CRC32_DATA8): Likewise. (BUILT_IN_CRC32_DATA16): Likewise. (BUILT_IN_CRC32_DATA32): Likewise. (BUILT_IN_CRC64_DATA8): Likewise. (BUILT_IN_CRC64_DATA16): Likewise. (BUILT_IN_CRC64_DATA32): Likewise. (BUILT_IN_CRC64_DATA64): Likewise. (BUILT_IN_REV_CRC8_DATA8): New builtin. (BUILT_IN_REV_CRC16_DATA8): Likewise. (BUILT_IN_REV_CRC16_DATA16): Likewise. (BUILT_IN_REV_CRC32_DATA8): Likewise. (BUILT_IN_REV_CRC32_DATA16): Likewise. (BUILT_IN_REV_CRC32_DATA32): Likewise. (BUILT_IN_REV_CRC64_DATA8): Likewise. (BUILT_IN_REV_CRC64_DATA16): Likewise. (BUILT_IN_REV_CRC64_DATA32): Likewise. (BUILT_IN_REV_CRC64_DATA64): Likewise. * builtins.h (expand_builtin_crc_table_based): New function declaration. * doc/extend.texti (__builtin_rev_crc8_data8, __builtin_rev_crc16_data16, __builtin_rev_crc16_data8, __builtin_rev_crc32_data32, __builtin_rev_crc32_data8, __builtin_rev_crc32_data16, __builtin_rev_crc64_data64, __builtin_rev_crc64_data8, __builtin_rev_crc64_data16, __builtin_rev_crc64_data32, __builtin_crc8_data8, __builtin_crc16_data16, __builtin_crc16_data8, __builtin_crc32_data32, __builtin_crc32_data8, __builtin_crc32_data16, __builtin_crc64_data64, __builtin_crc64_data8, __builtin_crc64_data16, __builtin_crc64_data32): Document. gcc/testsuite/ (BT_FN_UINT64_UINT64_UINT64_CONST_SIZE): Likewise. * builtins.cc (associated_internal_fn): Handle BUILT_IN_CRC8_DATA8, BUILT_IN_CRC16_DATA8, BUILT_IN_CRC16_DATA16, BUILT_IN_CRC32_DATA8, BUILT_IN_CRC32_DATA16, BUILT_IN_CRC32_DATA32, BUILT_IN_CRC64_DATA8, BUILT_IN_CRC64_DATA16, BUILT_IN_CRC64_DATA32, BUILT_IN_CRC64_DATA64, BUILT_IN_REV_CRC8_DATA8, BUILT_IN_REV_CRC16_DATA8, BUILT_IN_REV_CRC16_DATA16, BUILT_IN_REV_CRC32_DATA8, BUILT_IN_REV_CRC32_DATA16, BUILT_IN_REV_CRC32_DATA32. (expand_builtin_crc_table_based): New function. (expand_builtin): Handle BUILT_IN_CRC8_DATA8, BUILT_IN_CRC16_DATA8, BUILT_IN_CRC16_DATA16, BUILT_IN_CRC32_DATA8, BUILT_IN_CRC32_DATA16, BUILT_IN_CRC32_DATA32, BUILT_IN_CRC64_DATA8, BUILT_IN_CRC64_DATA16, BUILT_IN_CRC64_DATA32, BUILT_IN_CRC64_DATA64, BUILT_IN_REV_CRC8_DATA8, BUILT_IN_REV_CRC16_DATA8, BUILT_IN_REV_CRC16_DATA16, BUILT_IN_REV_CRC32_DATA8, BUILT_IN_REV_CRC32_DATA16, BUILT_IN_REV_CRC32_DATA32, BUILT_IN_REV_CRC64_DATA8, BUILT_IN_REV_CRC64_DATA16, BUILT_IN_REV_CRC64_DATA32, BUILT_IN_REV_CRC64_DATA64. * builtins.def (BUILT_IN_CRC8_DATA8): New builtin. (BUILT_IN_CRC16_DATA8): Likewise. (BUILT_IN_CRC16_DATA16): Likewise. (BUILT_IN_CRC32_DATA8): Likewise. (BUILT_IN_CRC32_DATA16): Likewise. (BUILT_IN_CRC32_DATA32): Likewise. (BUILT_IN_CRC64_DATA8): Likewise. (BUILT_IN_CRC64_DATA16): Likewise. (BUILT_IN_CRC64_DATA32): Likewise. (BUILT_IN_CRC64_DATA64): Likewise. (BUILT_IN_REV_CRC8_DATA8): New builtin. (BUILT_IN_REV_CRC16_DATA8): Likewise. (BUILT_IN_REV_CRC16_DATA16): Likewise. (BUILT_IN_REV_CRC32_DATA8): Likewise. (BUILT_IN_REV_CRC32_DATA16): Likewise. (BUILT_IN_REV_CRC32_DATA32): Likewise. (BUILT_IN_REV_CRC64_DATA8): Likewise. (BUILT_IN_REV_CRC64_DATA16): Likewise. (BUILT_IN_REV_CRC64_DATA32): Likewise. (BUILT_IN_REV_CRC64_DATA64): Likewise. * builtins.h (expand_builtin_crc_table_based): New function declaration. * doc/extend.texti (__builtin_rev_crc8_data8, __builtin_rev_crc16_data16, __builtin_rev_crc16_data8, __builtin_rev_crc32_data32, __builtin_rev_crc32_data8, __builtin_rev_crc32_data16, __builtin_rev_crc64_data64, __builtin_rev_crc64_data8, __builtin_rev_crc64_data16, __builtin_rev_crc64_data32, __builtin_crc8_data8, __builtin_crc16_data16, __builtin_crc16_data8, __builtin_crc32_data32, __builtin_crc32_data8, __builtin_crc32_data16, __builtin_crc64_data64, __builtin_crc64_data8, __builtin_crc64_data16, __builtin_crc64_data32): Document. gcc/testsuite/ * gcc.dg/crc-builtin-rev-target32.c * gcc.dg/crc-builtin-rev-target64.c * gcc.dg/crc-builtin-target32.c * gcc.dg/crc-builtin-target64.c Signed-off-by: Mariam Arutunian diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index c97d6bad1de..a0c4b8b9ca6 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -829,6 +829,26 @@ DEF_FUNCTION_TYPE_3 (BT_FN_PTR_SIZE_SIZE_PTRMODE, BT_PTR, BT_SIZE, BT_SIZE, BT_PTRMODE) DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_UINT8_PTRMODE, BT_VOID, BT_PTR, BT_UINT8, BT_PTRMODE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT8_UINT8_UINT8_CONST_SIZE, BT_UINT8, BT_UINT8, + BT_UINT8, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT16_UINT16_UINT8_CONST_SIZE, BT_UINT16, BT_UINT16, + BT_UINT8, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT16_UINT16_UINT16_CONST_SIZE, BT_UINT16, + BT_UINT16, BT_UINT16, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT32_UINT32_UINT8_CONST_SIZE, BT_UINT32, BT_UINT32, + BT_UINT8, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT32_UINT32_UINT16_CONST_SIZE, BT_UINT32, + BT_UINT32, BT_UINT16, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT32_UINT32_UINT32_CONST_SIZE, BT_UINT32, + BT_UINT32, BT_UINT32, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT64_UINT64_UINT8_CONST_SIZE, BT_UINT64, BT_UINT64, + BT_UINT8, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT64_UINT64_UINT16_CONST_SIZE, BT_UINT64, + BT_UINT64, BT_UINT16, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT64_UINT64_UINT32_CONST_SIZE, BT_UINT64, + BT_UINT64, BT_UINT32, BT_CONST_SIZE) +DEF_FUNCTION_TYPE_3 (BT_FN_UINT64_UINT64_UINT64_CONST_SIZE, BT_UINT64, + BT_UINT64, BT_UINT64, BT_CONST_SIZE) DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_FILEPTR, BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_FILEPTR) diff --git a/gcc/builtins.cc b/gcc/builtins.cc index f8d94c4b435..0d1751fca87 100644 --- a/gcc/builtins.cc +++ b/gcc/builtins.cc @@ -2207,7 +2207,28 @@ associated_internal_fn (built_in_function fn, tree return_type) if (REAL_MODE_FORMAT (TYPE_MODE (return_type))->b == 2) return IFN_LDEXP; return IFN_LAST; - + case BUILT_IN_CRC8_DATA8: + case BUILT_IN_CRC16_DATA8: + case BUILT_IN_CRC16_DATA16: + case BUILT_IN_CRC32_DATA8: + case BUILT_IN_CRC32_DATA16: + case BUILT_IN_CRC32_DATA32: + case BUILT_IN_CRC64_DATA8: + case BUILT_IN_CRC64_DATA16: + case BUILT_IN_CRC64_DATA32: + case BUILT_IN_CRC64_DATA64: + return IFN_CRC; + case BUILT_IN_REV_CRC8_DATA8: + case BUILT_IN_REV_CRC16_DATA8: + case BUILT_IN_REV_CRC16_DATA16: + case BUILT_IN_REV_CRC32_DATA8: + case BUILT_IN_REV_CRC32_DATA16: + case BUILT_IN_REV_CRC32_DATA32: + case BUILT_IN_REV_CRC64_DATA8: + case BUILT_IN_REV_CRC64_DATA16: + case BUILT_IN_REV_CRC64_DATA32: + case BUILT_IN_REV_CRC64_DATA64: + return IFN_CRC_REV; default: return IFN_LAST; } @@ -7751,6 +7772,37 @@ expand_speculation_safe_value (machine_mode mode, tree exp, rtx target, return targetm.speculation_safe_value (mode, target, val, failsafe); } +/* Expand CRC* or REV_CRC* built-ins. */ + +rtx +expand_builtin_crc_table_based (internal_fn fn, scalar_mode data_mode, + scalar_mode crc_mode, machine_mode mode, + tree exp, rtx target) +{ + tree rhs1 = CALL_EXPR_ARG (exp, 0); // crc + tree rhs2 = CALL_EXPR_ARG (exp, 1); // data + tree rhs3 = CALL_EXPR_ARG (exp, 2); // polynomial + + gcc_assert (word_mode >= crc_mode); + + if (!target || mode == VOIDmode) + target = gen_reg_rtx (crc_mode); + + rtx op1 = expand_normal (rhs1); + rtx op2 = expand_normal (rhs2); + gcc_assert (TREE_CODE (rhs3) == INTEGER_CST); + rtx op3 = gen_int_mode (TREE_INT_CST_LOW (rhs3), crc_mode); + + if (fn == IFN_CRC) + expand_crc_table_based (target, op1, op2, op3, data_mode); + else + /* If it's IFN_CRC_REV generate bit-reversed CRC. */ + expand_reversed_crc_table_based (target, op1, op2, op3, + data_mode, + generate_reflecting_code_standard); + return target; +} + /* Expand an expression EXP that calls a built-in function, with result going to TARGET if that's convenient (and in mode MODE if that's convenient). @@ -8928,6 +8980,66 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, mode = get_builtin_sync_mode (fcode - BUILT_IN_SPECULATION_SAFE_VALUE_1); return expand_speculation_safe_value (mode, exp, target, ignore); + case BUILT_IN_CRC8_DATA8: + return expand_builtin_crc_table_based (IFN_CRC, QImode, QImode, mode, + exp, target); + case BUILT_IN_CRC16_DATA8: + return expand_builtin_crc_table_based (IFN_CRC, HImode, QImode, mode, + exp, target); + case BUILT_IN_CRC16_DATA16: + return expand_builtin_crc_table_based (IFN_CRC, HImode, HImode, mode, + exp, target); + case BUILT_IN_CRC32_DATA8: + return expand_builtin_crc_table_based (IFN_CRC, SImode, QImode, mode, + exp, target); + case BUILT_IN_CRC32_DATA16: + return expand_builtin_crc_table_based (IFN_CRC, SImode, HImode, mode, + exp, target); + case BUILT_IN_CRC32_DATA32: + return expand_builtin_crc_table_based (IFN_CRC, SImode, SImode, mode, + exp, target); + case BUILT_IN_CRC64_DATA8: + return expand_builtin_crc_table_based (IFN_CRC, DImode, QImode, mode, + exp, target); + case BUILT_IN_CRC64_DATA16: + return expand_builtin_crc_table_based (IFN_CRC, DImode, HImode, mode, + exp, target); + case BUILT_IN_CRC64_DATA32: + return expand_builtin_crc_table_based (IFN_CRC, DImode, SImode, mode, + exp, target); + case BUILT_IN_CRC64_DATA64: + return expand_builtin_crc_table_based (IFN_CRC, DImode, DImode, mode, + exp, target); + case BUILT_IN_REV_CRC8_DATA8: + return expand_builtin_crc_table_based (IFN_CRC_REV, QImode, QImode, + mode, exp, target); + case BUILT_IN_REV_CRC16_DATA8: + return expand_builtin_crc_table_based (IFN_CRC_REV, HImode, QImode, + mode, exp, target); + case BUILT_IN_REV_CRC16_DATA16: + return expand_builtin_crc_table_based (IFN_CRC_REV, HImode, HImode, + mode, exp, target); + case BUILT_IN_REV_CRC32_DATA8: + return expand_builtin_crc_table_based (IFN_CRC_REV, SImode, QImode, + mode, exp, target); + case BUILT_IN_REV_CRC32_DATA16: + return expand_builtin_crc_table_based (IFN_CRC_REV, SImode, HImode, + mode, exp, target); + case BUILT_IN_REV_CRC32_DATA32: + return expand_builtin_crc_table_based (IFN_CRC_REV, SImode, SImode, + mode, exp, target); + case BUILT_IN_REV_CRC64_DATA8: + return expand_builtin_crc_table_based (IFN_CRC, DImode, QImode, mode, + exp, target); + case BUILT_IN_REV_CRC64_DATA16: + return expand_builtin_crc_table_based (IFN_CRC, DImode, HImode, mode, + exp, target); + case BUILT_IN_REV_CRC64_DATA32: + return expand_builtin_crc_table_based (IFN_CRC, DImode, SImode, mode, + exp, target); + case BUILT_IN_REV_CRC64_DATA64: + return expand_builtin_crc_table_based (IFN_CRC, DImode, DImode, mode, + exp, target); default: /* just do library call, if unknown builtin */ break; } diff --git a/gcc/builtins.def b/gcc/builtins.def index f6f3e104f6a..085602603d9 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -704,7 +704,26 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_Y1L, "y1l", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_M DEF_EXT_LIB_BUILTIN (BUILT_IN_YN, "yn", BT_FN_DOUBLE_INT_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO) DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO) - +DEF_GCC_BUILTIN (BUILT_IN_CRC8_DATA8, "crc8_data8", BT_FN_UINT8_UINT8_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC16_DATA8, "crc16_data8", BT_FN_UINT16_UINT16_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC16_DATA16, "crc16_data16", BT_FN_UINT16_UINT16_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC32_DATA8, "crc32_data8", BT_FN_UINT32_UINT32_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC32_DATA16, "crc32_data16", BT_FN_UINT32_UINT32_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC32_DATA32, "crc32_data32", BT_FN_UINT32_UINT32_UINT32_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC64_DATA8, "crc64_data8", BT_FN_UINT64_UINT64_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC64_DATA16, "crc64_data16", BT_FN_UINT64_UINT64_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC64_DATA32, "crc64_data32", BT_FN_UINT64_UINT64_UINT32_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_CRC64_DATA64, "crc64_data64", BT_FN_UINT64_UINT64_UINT64_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC8_DATA8, "rev_crc8_data8", BT_FN_UINT8_UINT8_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC16_DATA8, "rev_crc16_data8", BT_FN_UINT16_UINT16_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC16_DATA16, "rev_crc16_data16", BT_FN_UINT16_UINT16_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC32_DATA8, "rev_crc32_data8", BT_FN_UINT32_UINT32_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC32_DATA16, "rev_crc32_data16", BT_FN_UINT32_UINT32_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC32_DATA32, "rev_crc32_data32", BT_FN_UINT32_UINT32_UINT32_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC64_DATA8, "rev_crc64_data8", BT_FN_UINT64_UINT64_UINT8_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC64_DATA16, "rev_crc64_data16", BT_FN_UINT64_UINT64_UINT16_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC64_DATA32, "rev_crc64_data32", BT_FN_UINT64_UINT64_UINT32_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) +DEF_GCC_BUILTIN (BUILT_IN_REV_CRC64_DATA64, "rev_crc64_data64", BT_FN_UINT64_UINT64_UINT64_CONST_SIZE, ATTR_CONST_NOTHROW_LEAF_LIST) /* Category: _Complex math builtins. */ DEF_C99_COMPL_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING) DEF_C99_COMPL_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING) diff --git a/gcc/builtins.h b/gcc/builtins.h index 8d93f75a9a4..0094b9dcc3f 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -133,6 +133,9 @@ extern void expand_builtin_trap (void); extern void expand_ifn_atomic_bit_test_and (gcall *); extern void expand_ifn_atomic_compare_exchange (gcall *); extern void expand_ifn_atomic_op_fetch_cmp_0 (gcall *); +extern rtx expand_builtin_crc_table_based (internal_fn, scalar_mode, + scalar_mode, machine_mode, + tree, rtx); extern rtx expand_builtin (tree, rtx, rtx, machine_mode, int); extern enum built_in_function builtin_mathfn_code (const_tree); extern tree fold_builtin_expect (location_t, tree, tree, tree, tree); diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 8786249fb6f..932847b34f9 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -15835,6 +15835,115 @@ Returns the openacc gang, worker or vector size depending on whether @var{x} is 0, 1 or 2. @enddefbuiltin +@defbuiltin{uint8_t __builtin_rev_crc8_data8 (uint8_t @var{crc}, uint8_t @var{data}, uint8_t @var{poly})} +Returns the calculated 8-bit bit-reversed CRC using the initial CRC (8-bit), +data (8-bit) and the polynomial (8-bit). +@var{crc} is the initial CRC, @var{data} is the data and +@var{poly} is the polynomial without leading 1. +Table-based or clmul-based CRC may be used for the +calculation, depending on the target architecture. +@enddefbuiltin + +@defbuiltin{uint16_t __builtin_rev_crc16_data16 (uint16_t @var{crc}, uint16_t @var{data}, uint16_t @var{poly})} +Similar to @code{__builtin_rev_crc8_data8}, except the argument and return types +are 16-bit. +@enddefbuiltin + +@defbuiltin{uint16_t __builtin_rev_crc16_data8 (uint16_t @var{crc}, uint8_t @var{data}, uint16_t @var{poly})} +Similar to @code{__builtin_rev_crc16_data16}, except the @var{data} argument +type is 8-bit. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_rev_crc32_data32 (uint32_t @var{crc}, uint32_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_rev_crc8_data8}, except the argument and return types +are 32-bit and for the CRC calculation may be also used crc* machine instruction +depending on the target and the polynomial. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_rev_crc32_data8 (uint32_t @var{crc}, uint8_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_rev_crc32_data32}, except the @var{data} argument +type is 8-bit. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_rev_crc32_data16 (uint32_t @var{crc}, uint16_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_rev_crc32_data32}, except the @var{data} argument +type is 16-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_rev_crc64_data64 (uint64_t @var{crc}, uint64_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_rev_crc8_data8}, except the argument and return types +are 64-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_rev_crc64_data8 (uint64_t @var{crc}, uint8_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_rev_crc64_data64}, except the @var{data} argument type +is 8-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_rev_crc64_data16 (uint64_t @var{crc}, uint16_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_rev_crc64_data64}, except the @var{data} argument type +is 16-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_rev_crc64_data32 (uint64_t @var{crc}, uint32_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_rev_crc64_data64}, except the @var{data} argument type +is 32-bit. +@enddefbuiltin + +@defbuiltin{uint8_t __builtin_crc8_data8 (uint8_t @var{crc}, uint8_t @var{data}, uint8_t @var{poly})} +Returns the calculated 8-bit bit-forward CRC using the initial CRC (8-bit), +data (8-bit) and the polynomial (8-bit). +@var{crc} is the initial CRC, @var{data} is the data and +@var{poly} is the polynomial without leading 1. +Table-based or clmul-based CRC may be used for the +calculation, depending on the target architecture. +@enddefbuiltin + +@defbuiltin{uint16_t __builtin_crc16_data16 (uint16_t @var{crc}, uint16_t @var{data}, uint16_t @var{poly})} +Similar to @code{__builtin_crc8_data8}, except the argument and return types +are 16-bit. +@enddefbuiltin + +@defbuiltin{uint16_t __builtin_crc16_data8 (uint16_t @var{crc}, uint8_t @var{data}, uint16_t @var{poly})} +Similar to @code{__builtin_crc16_data16}, except the @var{data} argument type +is 8-bit. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_crc32_data32 (uint32_t @var{crc}, uint32_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_crc8_data8}, except the argument and return types +are 32-bit. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_crc32_data8 (uint32_t @var{crc}, uint8_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_crc32_data32}, except the @var{data} argument type +is 8-bit. +@enddefbuiltin + +@defbuiltin{uint32_t __builtin_crc32_data16 (uint32_t @var{crc}, uint16_t @var{data}, uint32_t @var{poly})} +Similar to @code{__builtin_crc32_data32}, except the @var{data} argument type +is 16-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_crc64_data64 (uint64_t @var{crc}, uint64_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_crc8_data8}, except the argument and return types +are 64-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_crc64_data8 (uint64_t @var{crc}, uint8_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_crc64_data64}, except the @var{data} argument type +is 8-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_crc64_data16 (uint64_t @var{crc}, uint16_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_crc64_data64}, except the @var{data} argument type +is 16-bit. +@enddefbuiltin + +@defbuiltin{uint64_t __builtin_crc64_data32 (uint64_t @var{crc}, uint32_t @var{data}, uint64_t @var{poly})} +Similar to @code{__builtin_crc64_data64}, except the @var{data} argument type +is 32-bit. +@enddefbuiltin + @node Target Builtins @section Built-in Functions Specific to Particular Target Machines diff --git a/gcc/testsuite/gcc.dg/crc-builtin-rev-target32.c b/gcc/testsuite/gcc.dg/crc-builtin-rev-target32.c new file mode 100644 index 00000000000..c068c14edce --- /dev/null +++ b/gcc/testsuite/gcc.dg/crc-builtin-rev-target32.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ + +#include + +int8_t rev_crc8_data8 () +{ + return __builtin_rev_crc8_data8 (0x34, 'a', 0x12); +} + +int16_t rev_crc16_data8 () +{ + return __builtin_rev_crc16_data8 (0x1234, 'a', 0x1021); +} + +int16_t rev_crc16_data16 () +{ + return __builtin_rev_crc16_data16 (0x1234, 0x3214, 0x1021); +} + +int32_t rev_crc32_data8 () +{ + return __builtin_rev_crc32_data8 (0xffffffff, 0x32, 0x4002123); +} + +int32_t rev_crc32_data16 () +{ + return __builtin_rev_crc32_data16 (0xffffffff, 0x3232, 0x4002123); +} + +int32_t rev_crc32_data32 () +{ + return __builtin_rev_crc32_data32 (0xffffffff, 0x123546ff, 0x4002123); +} + +/* { dg-final { scan-assembler "crc_table_for_crc_8_polynomial_0x12|mul"} } */ +/* { dg-final { scan-assembler "crc_table_for_crc_16_polynomial_0x1021|mul"} } */ +/* { dg-final { scan-assembler "crc_table_for_crc_32_polynomial_0x4002123|mul"} } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/crc-builtin-rev-target64.c b/gcc/testsuite/gcc.dg/crc-builtin-rev-target64.c new file mode 100644 index 00000000000..1eb6969068f --- /dev/null +++ b/gcc/testsuite/gcc.dg/crc-builtin-rev-target64.c @@ -0,0 +1,60 @@ +/* { dg-do compile { target lp64 } } */ +#include + +int8_t rev_crc8_data8 () +{ + return __builtin_rev_crc8_data8 (0x34, 'a', 0x12); +} + +int16_t rev_crc16_data8 () +{ + return __builtin_rev_crc16_data8 (0x1234, 'a', 0x1021); +} + +int16_t rev_crc16_data16 () +{ + return __builtin_rev_crc16_data16 (0x1234, 0x3214, 0x1021); +} + +int32_t rev_crc32_data8 () +{ + return __builtin_rev_crc32_data8 (0xffffffff, 0x32, 0x4002123); +} + +int32_t rev_crc32_data16 () +{ + return __builtin_rev_crc32_data16 (0xffffffff, 0x3232, 0x4002123); +} + +int32_t rev_crc32_data32 () +{ + return __builtin_rev_crc32_data32 (0xffffffff, 0x123546ff, 0x4002123); +} + +int64_t rev_crc64_data8 () +{ + return __builtin_rev_crc64_data8 (0xffffffffffffffff, 0x32, + 0x40021234002123); +} + +int64_t rev_crc64_data16 () +{ + return __builtin_rev_crc64_data16 (0xffffffffffffffff, 0x3232, + 0x40021234002123); +} + +int64_t rev_crc64_data32 () +{ + return __builtin_rev_crc64_data32 (0xffffffffffffffff, 0x123546ff, + 0x40021234002123); +} + +int64_t rev_crc64_data64 () +{ + return __builtin_rev_crc64_data64 (0xffffffffffffffff, 0x123546ff123546ff, + 0x40021234002123); +} + +/* { dg-final { scan-assembler "crc_table_for_crc_8_polynomial_0x12|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_16_polynomial_0x1021|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_32_polynomial_0x4002123|mul" } } */ \ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/crc-builtin-target32.c b/gcc/testsuite/gcc.dg/crc-builtin-target32.c new file mode 100644 index 00000000000..9cdd38f5364 --- /dev/null +++ b/gcc/testsuite/gcc.dg/crc-builtin-target32.c @@ -0,0 +1,37 @@ +/* { dg-do compile } */ + +#include + +int8_t crc8_data8 () +{ + return __builtin_crc8_data8 (0x34, 'a', 0x12); +} + +int16_t crc16_data8 () +{ + return __builtin_crc16_data8 (0x1234, 'a', 0x1021); +} + +int16_t crc16_data16 () +{ + return __builtin_crc16_data16 (0x1234, 0x3214, 0x1021); +} + +int32_t crc32_data8 () +{ + return __builtin_crc32_data8 (0xffffffff, 0x32, 0x4002123); +} + +int32_t crc32_data16 () +{ + return __builtin_crc32_data16 (0xffffffff, 0x3232, 0x4002123); +} + +int32_t crc32_data32 () +{ + return __builtin_crc32_data32 (0xffffffff, 0x123546ff, 0x4002123); +} + +/* { dg-final { scan-assembler "crc_table_for_crc_8_polynomial_0x12|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_16_polynomial_0x1021|mul"} } */ +/* { dg-final { scan-assembler "crc_table_for_crc_32_polynomial_0x4002123|mul"} } */ diff --git a/gcc/testsuite/gcc.dg/crc-builtin-target64.c b/gcc/testsuite/gcc.dg/crc-builtin-target64.c new file mode 100644 index 00000000000..41884be0fbc --- /dev/null +++ b/gcc/testsuite/gcc.dg/crc-builtin-target64.c @@ -0,0 +1,59 @@ +/* { dg-do compile { target lp64 } } */ +#include + +int8_t crc8_data8 () +{ + return __builtin_crc8_data8 (0x34, 'a', 0x12); +} + +int16_t crc16_data8 () +{ + return __builtin_crc16_data8 (0x1234, 'a', 0x1021); +} + +int16_t crc16_data16 () +{ + return __builtin_crc16_data16 (0x1234, 0x3214, 0x1021); +} + +int32_t crc32_data8 () +{ + return __builtin_crc32_data8 (0xffffffff, 0x32, 0x4002123); +} + +int32_t crc32_data16 () +{ + return __builtin_crc32_data16 (0xffffffff, 0x3232, 0x4002123); +} + +int32_t crc32_data32 () +{ + return __builtin_crc32_data32 (0xffffffff, 0x123546ff, 0x4002123); +} + +int64_t crc64_data8 () +{ + return __builtin_crc64_data8 (0xffffffffffffffff, 0x32, 0x40021234002123); +} + +int64_t crc64_data16 () +{ + return __builtin_crc64_data16 (0xffffffffffffffff, 0x3232, 0x40021234002123); +} + +int64_t crc64_data32 () +{ + return __builtin_crc64_data32 (0xffffffffffffffff, 0x123546ff, + 0x40021234002123); +} + +int64_t crc64_data64 () +{ + return __builtin_crc64_data64 (0xffffffffffffffff, 0x123546ff123546ff, + 0x40021234002123); +} + +/* { dg-final { scan-assembler "crc_table_for_crc_8_polynomial_0x12|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_16_polynomial_0x1021|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_32_polynomial_0x4002123|mul" } } */ +/* { dg-final { scan-assembler "crc_table_for_crc_64_polynomial_0x40021234002123|mul" } } */ -- 2.25.1