Re: [PATCH 4/5] aarch64: Implement 128-bit extension to ACLE sysreg r/w builtins

2023-11-07 Thread Richard Sandiford
Victor Do Nascimento  writes:
> 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.
> ---
>  gcc/config/aarch64/aarch64-builtins.cc | 50 +-
>  gcc/config/aarch64/aarch64-protos.h|  2 +-
>  gcc/config/aarch64/aarch64.cc  |  6 +++-
>  gcc/config/aarch64/aarch64.md  | 18 ++
>  gcc/config/aarch64/arm_acle.h  | 11 ++
>  5 files changed, 77 insertions(+), 10 deletions(-)
>
> diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
> b/gcc/config/aarch64/aarch64-builtins.cc
> index c5f20f68bca..40d3788b5e0 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 suppport 
> requires "
> +  "the +d128 Armv9.4-A extension");

Elsewhere we've put feature names in quotes, since they're code
or code-adjacent.  Probably also best to drop Armv9.4-A part,
since the requirement is tied only to +d128.  So:

  error_at (EXPR_LOCATION (exp),
"128-bit system register suppport requires the %"
" extension");

(formatted that way to avoid a long line).

> +  return const0_rtx;
> +}
>  
>/* Argument 0 (system register name) must be a string literal.  */
>gcc_assert (TREE_CODE (arg0) == ADDR_EXPR
> @@ -2741,7 +2765,7 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int 
> fcode)
>  sysreg_name[pos] = TOLOWER (sysreg_name[pos]);
>  
>const char* name_output = aarch64_retrieve_sysreg ((const char *) 
> sysreg_name,
> -  write_op);
> +  write_op, op128);
>if (name_output == NULL)
>  {
>error_at (EXPR_LOCATION (exp), "invalid system register name 
> provided");
> @@ -2760,13 +2784,17 @@ aarch64_expand_rwsr_

[PATCH 4/5] aarch64: Implement 128-bit extension to ACLE sysreg r/w builtins

2023-11-07 Thread Victor Do Nascimento
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.
---
 gcc/config/aarch64/aarch64-builtins.cc | 50 +-
 gcc/config/aarch64/aarch64-protos.h|  2 +-
 gcc/config/aarch64/aarch64.cc  |  6 +++-
 gcc/config/aarch64/aarch64.md  | 18 ++
 gcc/config/aarch64/arm_acle.h  | 11 ++
 5 files changed, 77 insertions(+), 10 deletions(-)

diff --git a/gcc/config/aarch64/aarch64-builtins.cc 
b/gcc/config/aarch64/aarch64-builtins.cc
index c5f20f68bca..40d3788b5e0 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 suppport 
requires "
+"the +d128 Armv9.4-A extension");
+  return const0_rtx;
+}
 
   /* Argument 0 (system register name) must be a string literal.  */
   gcc_assert (TREE_CODE (arg0) == ADDR_EXPR
@@ -2741,7 +2765,7 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int 
fcode)
 sysreg_name[pos] = TOLOWER (sysreg_name[pos]);
 
   const char* name_output = aarch64_retrieve_sysreg ((const char *) 
sysreg_name,
-write_op);
+write_op, op128);
   if (name_output == NULL)
 {
   error_at (EXPR_LOCATION (exp), "invalid system register name provided");
@@ -2760,13 +2784,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);