@@ -815,11 +815,13 @@ enum aarch64_builtins
815815 AARCH64_RSR64 ,
816816 AARCH64_RSRF ,
817817 AARCH64_RSRF64 ,
818+ AARCH64_RSR128 ,
818819 AARCH64_WSR ,
819820 AARCH64_WSRP ,
820821 AARCH64_WSR64 ,
821822 AARCH64_WSRF ,
822823 AARCH64_WSRF64 ,
824+ AARCH64_WSR128 ,
823825 AARCH64_BUILTIN_MAX
824826};
825827
@@ -1842,6 +1844,10 @@ aarch64_init_rwsr_builtins (void)
18421844 = build_function_type_list (double_type_node, const_char_ptr_type, NULL );
18431845 AARCH64_INIT_RWSR_BUILTINS_DECL (RSRF64 , rsrf64, fntype);
18441846
1847+ fntype
1848+ = build_function_type_list (uint128_type_node, const_char_ptr_type, NULL );
1849+ AARCH64_INIT_RWSR_BUILTINS_DECL (RSR128 , rsr128, fntype);
1850+
18451851 fntype
18461852 = build_function_type_list (void_type_node, const_char_ptr_type,
18471853 uint32_type_node, NULL );
@@ -1867,6 +1873,12 @@ aarch64_init_rwsr_builtins (void)
18671873 = build_function_type_list (void_type_node, const_char_ptr_type,
18681874 double_type_node, NULL );
18691875 AARCH64_INIT_RWSR_BUILTINS_DECL (WSRF64 , wsrf64, fntype);
1876+
1877+ fntype
1878+ = build_function_type_list (void_type_node, const_char_ptr_type,
1879+ uint128_type_node, NULL );
1880+ AARCH64_INIT_RWSR_BUILTINS_DECL (WSR128 , wsr128, fntype);
1881+
18701882}
18711883
18721884/* Initialize the memory tagging extension (MTE) builtins. */
@@ -2710,6 +2722,7 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27102722 tree arg0, arg1;
27112723 rtx const_str, input_val, subreg;
27122724 enum machine_mode mode;
2725+ enum insn_code icode;
27132726 class expand_operand ops[2 ];
27142727
27152728 arg0 = CALL_EXPR_ARG (exp, 0 );
@@ -2718,7 +2731,18 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27182731 || fcode == AARCH64_WSRP
27192732 || fcode == AARCH64_WSR64
27202733 || fcode == AARCH64_WSRF
2721- || fcode == AARCH64_WSRF64 );
2734+ || fcode == AARCH64_WSRF64
2735+ || fcode == AARCH64_WSR128 );
2736+
2737+ bool op128 = (fcode == AARCH64_RSR128 || fcode == AARCH64_WSR128 );
2738+ enum machine_mode sysreg_mode = op128 ? TImode : DImode;
2739+
2740+ if (op128 && !TARGET_D128 )
2741+ {
2742+ error_at (EXPR_LOCATION (exp), " 128-bit system register support requires"
2743+ " the %<d128%> extension" );
2744+ return const0_rtx;
2745+ }
27222746
27232747 /* Argument 0 (system register name) must be a string literal. */
27242748 gcc_assert (TREE_CODE (arg0) == ADDR_EXPR
@@ -2740,7 +2764,8 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27402764 for (unsigned pos = 0 ; pos <= len; pos++)
27412765 sysreg_name[pos] = TOLOWER (sysreg_name[pos]);
27422766
2743- const char *name_output = aarch64_retrieve_sysreg (sysreg_name, write_op);
2767+ const char * name_output = aarch64_retrieve_sysreg ((const char *) sysreg_name,
2768+ write_op, op128);
27442769 if (name_output == NULL )
27452770 {
27462771 error_at (EXPR_LOCATION (exp), " invalid system register name %qs" ,
@@ -2760,13 +2785,17 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27602785 mode = TYPE_MODE (TREE_TYPE (arg1));
27612786 input_val = copy_to_mode_reg (mode, expand_normal (arg1));
27622787
2788+ icode = (op128 ? CODE_FOR_aarch64_write_sysregti
2789+ : CODE_FOR_aarch64_write_sysregdi);
2790+
27632791 switch (fcode)
27642792 {
27652793 case AARCH64_WSR :
27662794 case AARCH64_WSRP :
27672795 case AARCH64_WSR64 :
27682796 case AARCH64_WSRF64 :
2769- subreg = lowpart_subreg (DImode, input_val, mode);
2797+ case AARCH64_WSR128 :
2798+ subreg = lowpart_subreg (sysreg_mode, input_val, mode);
27702799 break ;
27712800 case AARCH64_WSRF :
27722801 subreg = gen_lowpart_SUBREG (SImode, input_val);
@@ -2775,19 +2804,22 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27752804 }
27762805
27772806 create_fixed_operand (&ops[0 ], const_str);
2778- create_input_operand (&ops[1 ], subreg, DImode );
2779- expand_insn (CODE_FOR_aarch64_write_sysregdi , 2 , ops);
2807+ create_input_operand (&ops[1 ], subreg, sysreg_mode );
2808+ expand_insn (icode , 2 , ops);
27802809
27812810 return target;
27822811 }
27832812
27842813 /* Read operations are implied by !write_op. */
27852814 gcc_assert (call_expr_nargs (exp) == 1 );
27862815
2816+ icode = (op128 ? CODE_FOR_aarch64_read_sysregti
2817+ : CODE_FOR_aarch64_read_sysregdi);
2818+
27872819 /* Emit the initial read_sysregdi rtx. */
2788- create_output_operand (&ops[0 ], target, DImode );
2820+ create_output_operand (&ops[0 ], target, sysreg_mode );
27892821 create_fixed_operand (&ops[1 ], const_str);
2790- expand_insn (CODE_FOR_aarch64_read_sysregdi , 2 , ops);
2822+ expand_insn (icode , 2 , ops);
27912823 target = ops[0 ].value ;
27922824
27932825 /* Do any necessary post-processing on the result. */
@@ -2797,7 +2829,8 @@ aarch64_expand_rwsr_builtin (tree exp, rtx target, int fcode)
27972829 case AARCH64_RSRP :
27982830 case AARCH64_RSR64 :
27992831 case AARCH64_RSRF64 :
2800- return lowpart_subreg (TYPE_MODE (TREE_TYPE (exp)), target, DImode);
2832+ case AARCH64_RSR128 :
2833+ return lowpart_subreg (TYPE_MODE (TREE_TYPE (exp)), target, sysreg_mode);
28012834 case AARCH64_RSRF :
28022835 subreg = gen_lowpart_SUBREG (SImode, target);
28032836 return gen_lowpart_SUBREG (SFmode, subreg);
@@ -3044,11 +3077,13 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
30443077 case AARCH64_RSR64 :
30453078 case AARCH64_RSRF :
30463079 case AARCH64_RSRF64 :
3080+ case AARCH64_RSR128 :
30473081 case AARCH64_WSR :
30483082 case AARCH64_WSRP :
30493083 case AARCH64_WSR64 :
30503084 case AARCH64_WSRF :
30513085 case AARCH64_WSRF64 :
3086+ case AARCH64_WSR128 :
30523087 return aarch64_expand_rwsr_builtin (exp, target, fcode);
30533088 }
30543089
0 commit comments