From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 7922) id 09BF63858003; Wed, 6 Dec 2023 21:23:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 09BF63858003 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1701897786; bh=sYTg/wsKDnFaUAnK5PLJlbnOSBzOSMPLw6YT4grhAHI=; h=From:To:Subject:Date:From; b=rbwrWXv0/Zz6WsE1n+Tt6lZw+fUZmK/PoTO5ug4e3mH1k+X+5yuDySTiUo7z9tcks VM0E9ySpdo1GLgOnL4bDIyPJ5l3UzBPvWYNSHf7DjnLNLivF9RjETrPAigq2SzgPQC f+jui0heUhszqTZ6aeZnCHNeRCFKgysRTT+ub/No= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Victor Do Nascimento To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-6235] aarch64: Implement 128-bit extension to ACLE sysreg r/w builtins X-Act-Checkin: gcc X-Git-Author: Victor Do Nascimento X-Git-Refname: refs/heads/master X-Git-Oldrev: eac59af05aa5d7b420408b12865437dbc8a54218 X-Git-Newrev: 88157c88172b06f1afb6136e9bd8fce1de5ba823 Message-Id: <20231206212306.09BF63858003@sourceware.org> Date: Wed, 6 Dec 2023 21:23:06 +0000 (GMT) List-Id: https://gcc.gnu.org/g:88157c88172b06f1afb6136e9bd8fce1de5ba823 commit r14-6235-g88157c88172b06f1afb6136e9bd8fce1de5ba823 Author: Victor Do Nascimento Date: Sun Oct 29 00:38:59 2023 +0100 aarch64: Implement 128-bit extension to ACLE sysreg r/w builtins Implement the ACLE builtins for 128-bit system register manipulation: * __uint128_t __arm_rsr128(const char *special_register); * void __arm_wsr128(const char *special_register, __uint128_t value); gcc/ChangeLog: * config/aarch64/aarch64-builtins.cc (AARCH64_RSR128): New `enum aarch64_builtins' value. (AARCH64_WSR128): Likewise. (aarch64_init_rwsr_builtins): Init `__builtin_aarch64_rsr128' and `__builtin_aarch64_wsr128' builtins. (aarch64_expand_rwsr_builtin): Extend function to handle `__builtin_aarch64_{rsr|wsr}128'. * config/aarch64/aarch64-protos.h (aarch64_retrieve_sysreg): Update function signature. * config/aarch64/aarch64.cc (F_REG_128): New. (aarch64_retrieve_sysreg): Add 128-bit register mode check. * config/aarch64/aarch64.md (UNSPEC_SYSREG_RTI): New. (UNSPEC_SYSREG_WTI): Likewise. (aarch64_read_sysregti): Likewise. (aarch64_write_sysregti): Likewise. * config/aarch64/arm_acle.h (__arm_rsr128): New. (__arm_wsr128): Likewise. Diff: --- gcc/config/aarch64/aarch64-builtins.cc | 51 ++++++++++++++++++++++++++++------ gcc/config/aarch64/aarch64-protos.h | 2 +- gcc/config/aarch64/aarch64.cc | 9 ++++-- gcc/config/aarch64/aarch64.md | 18 ++++++++++++ gcc/config/aarch64/arm_acle.h | 11 ++++++++ 5 files changed, 80 insertions(+), 11 deletions(-) diff --git a/gcc/config/aarch64/aarch64-builtins.cc b/gcc/config/aarch64/aarch64-builtins.cc index f780b1094f3..452ff19f89b 100644 --- a/gcc/config/aarch64/aarch64-builtins.cc +++ b/gcc/config/aarch64/aarch64-builtins.cc @@ -815,11 +815,13 @@ enum aarch64_builtins AARCH64_RSR64, AARCH64_RSRF, AARCH64_RSRF64, + AARCH64_RSR128, AARCH64_WSR, AARCH64_WSRP, AARCH64_WSR64, AARCH64_WSRF, AARCH64_WSRF64, + AARCH64_WSR128, AARCH64_BUILTIN_MAX }; @@ -1842,6 +1844,10 @@ aarch64_init_rwsr_builtins (void) = build_function_type_list (double_type_node, const_char_ptr_type, NULL); AARCH64_INIT_RWSR_BUILTINS_DECL (RSRF64, rsrf64, fntype); + fntype + = build_function_type_list (uint128_type_node, const_char_ptr_type, NULL); + AARCH64_INIT_RWSR_BUILTINS_DECL (RSR128, rsr128, fntype); + fntype = build_function_type_list (void_type_node, const_char_ptr_type, uint32_type_node, NULL); @@ -1867,6 +1873,12 @@ aarch64_init_rwsr_builtins (void) = build_function_type_list (void_type_node, const_char_ptr_type, double_type_node, NULL); AARCH64_INIT_RWSR_BUILTINS_DECL (WSRF64, wsrf64, fntype); + + fntype + = build_function_type_list (void_type_node, const_char_ptr_type, + uint128_type_node, NULL); + AARCH64_INIT_RWSR_BUILTINS_DECL (WSR128, wsr128, fntype); + } /* Initialize the memory tagging extension (MTE) builtins. */ @@ -2710,6 +2722,7 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) tree arg0, arg1; rtx const_str, input_val, subreg; enum machine_mode mode; + enum insn_code icode; class expand_operand ops[2]; arg0 = CALL_EXPR_ARG (exp, 0); @@ -2718,7 +2731,18 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) || fcode == AARCH64_WSRP || fcode == AARCH64_WSR64 || fcode == AARCH64_WSRF - || fcode == AARCH64_WSRF64); + || fcode == AARCH64_WSRF64 + || fcode == AARCH64_WSR128); + + bool op128 = (fcode == AARCH64_RSR128 || fcode == AARCH64_WSR128); + enum machine_mode sysreg_mode = op128 ? TImode : DImode; + + if (op128 && !TARGET_D128) + { + error_at (EXPR_LOCATION (exp), "128-bit system register support requires" + " the % extension"); + return const0_rtx; + } /* Argument 0 (system register name) must be a string literal. */ gcc_assert (TREE_CODE (arg0) == ADDR_EXPR @@ -2740,7 +2764,8 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) for (unsigned pos = 0; pos <= len; pos++) sysreg_name[pos] = TOLOWER (sysreg_name[pos]); - const char *name_output = aarch64_retrieve_sysreg (sysreg_name, write_op); + const char* name_output = aarch64_retrieve_sysreg ((const char *) sysreg_name, + write_op, op128); if (name_output == NULL) { error_at (EXPR_LOCATION (exp), "invalid system register name %qs", @@ -2760,13 +2785,17 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) mode = TYPE_MODE (TREE_TYPE (arg1)); input_val = copy_to_mode_reg (mode, expand_normal (arg1)); + icode = (op128 ? CODE_FOR_aarch64_write_sysregti + : CODE_FOR_aarch64_write_sysregdi); + switch (fcode) { case AARCH64_WSR: case AARCH64_WSRP: case AARCH64_WSR64: case AARCH64_WSRF64: - subreg = lowpart_subreg (DImode, input_val, mode); + case AARCH64_WSR128: + subreg = lowpart_subreg (sysreg_mode, input_val, mode); break; case AARCH64_WSRF: subreg = gen_lowpart_SUBREG (SImode, input_val); @@ -2775,8 +2804,8 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) } create_fixed_operand (&ops[0], const_str); - create_input_operand (&ops[1], subreg, DImode); - expand_insn (CODE_FOR_aarch64_write_sysregdi, 2, ops); + create_input_operand (&ops[1], subreg, sysreg_mode); + expand_insn (icode, 2, ops); return target; } @@ -2784,10 +2813,13 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) /* Read operations are implied by !write_op. */ gcc_assert (call_expr_nargs (exp) == 1); + icode = (op128 ? CODE_FOR_aarch64_read_sysregti + : CODE_FOR_aarch64_read_sysregdi); + /* Emit the initial read_sysregdi rtx. */ - create_output_operand (&ops[0], target, DImode); + create_output_operand (&ops[0], target, sysreg_mode); create_fixed_operand (&ops[1], const_str); - expand_insn (CODE_FOR_aarch64_read_sysregdi, 2, ops); + expand_insn (icode, 2, ops); target = ops[0].value; /* Do any necessary post-processing on the result. */ @@ -2797,7 +2829,8 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode) case AARCH64_RSRP: case AARCH64_RSR64: case AARCH64_RSRF64: - return lowpart_subreg (TYPE_MODE (TREE_TYPE (exp)), target, DImode); + case AARCH64_RSR128: + return lowpart_subreg (TYPE_MODE (TREE_TYPE (exp)), target, sysreg_mode); case AARCH64_RSRF: subreg = gen_lowpart_SUBREG (SImode, target); return gen_lowpart_SUBREG (SFmode, subreg); @@ -3044,11 +3077,13 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target, case AARCH64_RSR64: case AARCH64_RSRF: case AARCH64_RSRF64: + case AARCH64_RSR128: case AARCH64_WSR: case AARCH64_WSRP: case AARCH64_WSR64: case AARCH64_WSRF: case AARCH64_WSRF64: + case AARCH64_WSR128: return aarch64_expand_rwsr_builtin (exp, target, fcode); } diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 60ff61f6d54..f2075a17732 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -840,7 +840,7 @@ bool aarch64_sve_ptrue_svpattern_p (rtx, struct simd_immediate_info *); bool aarch64_simd_valid_immediate (rtx, struct simd_immediate_info *, enum simd_immediate_check w = AARCH64_CHECK_MOV); bool aarch64_valid_sysreg_name_p (const char *); -const char *aarch64_retrieve_sysreg (const char *, bool); +const char *aarch64_retrieve_sysreg (const char *, bool, bool); rtx aarch64_check_zero_based_sve_index_immediate (rtx); bool aarch64_maybe_generate_simd_constant (rtx, rtx, machine_mode); bool aarch64_simd_special_constant_p (rtx, machine_mode); diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc index fd44e5922a2..8f50a70083d 100644 --- a/gcc/config/aarch64/aarch64.cc +++ b/gcc/config/aarch64/aarch64.cc @@ -498,6 +498,8 @@ typedef struct { #define F_ARCHEXT (1 << 4) /* Flag indicating register name is alias for another system register. */ #define F_REG_ALIAS (1 << 5) +/* Flag indicatinig registers which may be implemented with 128-bits. */ +#define F_REG_128 (1 << 6) /* Database of system registers, their encodings and architectural requirements. */ @@ -29083,9 +29085,10 @@ aarch64_valid_sysreg_name_p (const char *regname) /* Return the generic sysreg specification for a valid system register name, otherwise NULL. WRITE_P is true iff the register is being - written to. */ + written to. IS128OP indicates the requested system register should + be checked for a 128-bit implementation. */ const char * -aarch64_retrieve_sysreg (const char *regname, bool write_p) +aarch64_retrieve_sysreg (const char *regname, bool write_p, bool is128op) { const sysreg_t *sysreg = aarch64_lookup_sysreg_map (regname); if (sysreg == NULL) @@ -29095,6 +29098,8 @@ aarch64_retrieve_sysreg (const char *regname, bool write_p) else return NULL; } + if (is128op && !(sysreg->properties & F_REG_128)) + return NULL; if ((write_p && (sysreg->properties & F_REG_READ)) || (!write_p && (sysreg->properties & F_REG_WRITE))) return NULL; diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index a6d5e8c2a1a..38da76a1ee2 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -339,7 +339,9 @@ UNSPEC_RDFFR UNSPEC_WRFFR UNSPEC_SYSREG_RDI + UNSPEC_SYSREG_RTI UNSPEC_SYSREG_WDI + UNSPEC_SYSREG_WTI ;; Represents an SVE-style lane index, in which the indexing applies ;; within the containing 128-bit block. UNSPEC_SVE_LANE_SELECT @@ -558,6 +560,14 @@ "mrs\t%x0, %1" ) +(define_insn "aarch64_read_sysregti" + [(set (match_operand:TI 0 "register_operand" "=r") + (unspec_volatile:TI [(match_operand 1 "aarch64_sysreg_string" "")] + UNSPEC_SYSREG_RTI))] + "TARGET_D128" + "mrrs\t%x0, %H0, %x1" +) + (define_insn "aarch64_write_sysregdi" [(unspec_volatile:DI [(match_operand 0 "aarch64_sysreg_string" "") (match_operand:DI 1 "register_operand" "rZ")] @@ -566,6 +576,14 @@ "msr\t%0, %x1" ) +(define_insn "aarch64_write_sysregti" + [(unspec_volatile:TI [(match_operand 0 "aarch64_sysreg_string" "") + (match_operand:TI 1 "register_operand" "r")] + UNSPEC_SYSREG_WTI)] + "TARGET_D128" + "msrr\t%x0, %x1, %H1" +) + (define_insn "indirect_jump" [(set (pc) (match_operand:DI 0 "register_operand" "r"))] "" diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h index 71ada878299..80282b361a4 100644 --- a/gcc/config/aarch64/arm_acle.h +++ b/gcc/config/aarch64/arm_acle.h @@ -344,6 +344,17 @@ __rndrrs (uint64_t *__res) #define __arm_wsrf64(__regname, __value) \ __builtin_aarch64_wsrf64 (__regname, __value) +#pragma GCC push_options +#pragma GCC target ("+nothing+d128") + +#define __arm_rsr128(__regname) \ + __builtin_aarch64_rsr128 (__regname) + +#define __arm_wsr128(__regname, __value) \ + __builtin_aarch64_wsr128 (__regname, __value) + +#pragma GCC pop_options + #ifdef __cplusplus } #endif