From patchwork Fri Nov 8 14:48:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Khrustalev X-Patchwork-Id: 2008497 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org 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 4XlMLH6kLNz1xyM for ; Sat, 9 Nov 2024 01:50:15 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 2BAE93857C6A for ; Fri, 8 Nov 2024 14:50:14 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by sourceware.org (Postfix) with ESMTP id 9BDC73858C32; Fri, 8 Nov 2024 14:49:41 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 9BDC73858C32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 9BDC73858C32 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731077385; cv=none; b=iOCxYQt83lEy82F9MOZwWNuCN7UA+HZdoTlfQ5meuPAS9bbTQZBGmrCmjhhUJrrVJci20RXiqMfuy/XJ0bXHSWK1gUMAgqaZThLUZNgm0E9IbtLTcUilulNGwWtzgYmMSizthPqE3aouwj8GkzvLTx154/r2NMUoXpjMeBebR08= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731077385; c=relaxed/simple; bh=Z8e3V4O4nrZ+ux5kmYc7iPA1JlXQvT7uXJPGeFBiqU8=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=t2IxudenK6kBKnTKwQVppgEy2AYZp1axeV2AWlixaBbwSFuJj6QdRu7g1wYWBpTUuoF33cpHrdStXZIFxcqpJ5nCVl9c6sbvhjBGRAep0TUdrWQ8Ocvfs3Qbhe/Mk61sWkVXxA9oVsLVFBodJQXAKl4jq3gE3+J1fdJsOHbK+eI= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 484EE497; Fri, 8 Nov 2024 06:50:11 -0800 (PST) Received: from udebian.localdomain (unknown [10.57.26.225]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 310BF3F528; Fri, 8 Nov 2024 06:49:40 -0800 (PST) From: Yury Khrustalev To: gcc-patches@gcc.gnu.org Cc: nsz@gcc.gnu.org, richard.earnshaw@arm.com, matthieu.longo@arm.com, richard.ball@arm.com, richard.sandiford@arm.com, ktkachov@nvidia.com, john.brawn@arm.com Subject: [PATCH v3 08/23] aarch64: Add GCS builtins Date: Fri, 8 Nov 2024 14:48:01 +0000 Message-Id: <20241108144816.2681175-9-yury.khrustalev@arm.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241108144816.2681175-1-yury.khrustalev@arm.com> References: <20241108144816.2681175-1-yury.khrustalev@arm.com> MIME-Version: 1.0 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 From: Szabolcs Nagy Add new builtins for GCS: void *__builtin_aarch64_gcspr (void) uint64_t __builtin_aarch64_gcspopm (void) void *__builtin_aarch64_gcsss (void *) The builtins are always enabled, but should be used behind runtime checks in case the target does not support GCS. They are thin wrappers around the corresponding instructions. The GCS pointer is modelled with void * type (normal stores do not work on GCS memory, but it is writable via the gcsss operation or via GCSSTR if enabled so not const) and an entry on the GCS is modelled with uint64_t (since it has fixed size and can be a token that's not a pointer). gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (enum aarch64_builtins): Add AARCH64_BUILTIN_GCSPR, AARCH64_BUILTIN_GCSPOPM, AARCH64_BUILTIN_GCSSS. (aarch64_init_gcs_builtins): New. (aarch64_general_init_builtins): Call aarch64_init_gcs_builtins. (aarch64_expand_gcs_builtin): New. (aarch64_general_expand_builtin): Call aarch64_expand_gcs_builtin. --- gcc/config/aarch64/aarch64-builtins.cc | 78 ++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index e693a14f4f3..6101f252bfd 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -878,6 +878,9 @@ enum aarch64_builtins AARCH64_PLIX, /* Armv8.9-A / Armv9.4-A builtins. */ AARCH64_BUILTIN_CHKFEAT, + AARCH64_BUILTIN_GCSPR, + AARCH64_BUILTIN_GCSPOPM, + AARCH64_BUILTIN_GCSSS, AARCH64_BUILTIN_MAX }; @@ -2240,6 +2243,29 @@ aarch64_init_fpsr_fpcr_builtins (void) AARCH64_BUILTIN_SET_FPSR64); } +/* Add builtins for Guarded Control Stack instructions. */ + +static void +aarch64_init_gcs_builtins (void) +{ + tree ftype; + + ftype = build_function_type_list (ptr_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSPR] + = aarch64_general_add_builtin ("__builtin_aarch64_gcspr", ftype, + AARCH64_BUILTIN_GCSPR); + + ftype = build_function_type_list (uint64_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSPOPM] + = aarch64_general_add_builtin ("__builtin_aarch64_gcspopm", ftype, + AARCH64_BUILTIN_GCSPOPM); + + ftype = build_function_type_list (ptr_type_node, ptr_type_node, NULL); + aarch64_builtin_decls[AARCH64_BUILTIN_GCSSS] + = aarch64_general_add_builtin ("__builtin_aarch64_gcsss", ftype, + AARCH64_BUILTIN_GCSSS); +} + /* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */ void @@ -2287,6 +2313,8 @@ aarch64_general_init_builtins (void) = aarch64_general_add_builtin ("__builtin_aarch64_chkfeat", ftype_chkfeat, AARCH64_BUILTIN_CHKFEAT); + aarch64_init_gcs_builtins (); + if (in_lto_p) handle_arm_acle_h (); } @@ -3381,6 +3409,51 @@ aarch64_expand_fpsr_fpcr_getter (enum insn_code icode, machine_mode mode, return op.value; } +/* Expand GCS builtin EXP with code FCODE, putting the result + into TARGET. If IGNORE is true the return value is ignored. */ + +rtx +aarch64_expand_gcs_builtin (tree exp, rtx target, int fcode, int ignore) +{ + if (fcode == AARCH64_BUILTIN_GCSPR) + { + expand_operand op; + create_output_operand (&op, target, DImode); + expand_insn (CODE_FOR_aarch64_load_gcspr, 1, &op); + return op.value; + } + if (fcode == AARCH64_BUILTIN_GCSPOPM && ignore) + { + expand_insn (CODE_FOR_aarch64_gcspopm_xzr, 0, 0); + return target; + } + if (fcode == AARCH64_BUILTIN_GCSPOPM) + { + rtx tmp = gen_reg_rtx (DImode); + emit_move_insn (tmp, const0_rtx); + expand_operand ops[2]; + create_output_operand (&ops[0], target, Pmode); + create_input_operand (&ops[1], tmp, Pmode); + expand_insn (CODE_FOR_aarch64_gcspopm, 2, ops); + return ops[0].value; + } + if (fcode == AARCH64_BUILTIN_GCSSS) + { + expand_operand opnd; + rtx arg = expand_normal (CALL_EXPR_ARG (exp, 0)); + create_input_operand (&opnd, arg, Pmode); + expand_insn (CODE_FOR_aarch64_gcsss1, 1, &opnd); + expand_operand ops[2]; + rtx tmp = gen_reg_rtx (DImode); + emit_move_insn (tmp, const0_rtx); + create_output_operand (&ops[0], target, Pmode); + create_input_operand (&ops[1], tmp, Pmode); + expand_insn (CODE_FOR_aarch64_gcsss2, 2, ops); + return ops[0].value; + } + gcc_unreachable (); +} + /* Expand an expression EXP that calls built-in function FCODE, with result going to TARGET if that's convenient. IGNORE is true if the result of the builtin is ignored. */ @@ -3515,6 +3588,11 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, expand_insn (CODE_FOR_aarch64_chkfeat, 0, 0); return copy_to_reg (x16_reg); } + + case AARCH64_BUILTIN_GCSPR: + case AARCH64_BUILTIN_GCSPOPM: + case AARCH64_BUILTIN_GCSSS: + return aarch64_expand_gcs_builtin (exp, target, fcode, ignore); } if (fcode >= AARCH64_SIMD_BUILTIN_BASE && fcode <= AARCH64_SIMD_BUILTIN_MAX)