AARCH64_BUILTIN_GET_FPSR,
AARCH64_BUILTIN_SET_FPSR,
+ AARCH64_BUILTIN_GET_FPCR64,
+ AARCH64_BUILTIN_SET_FPCR64,
+ AARCH64_BUILTIN_GET_FPSR64,
+ AARCH64_BUILTIN_SET_FPSR64,
+
AARCH64_BUILTIN_RSQRT_DF,
AARCH64_BUILTIN_RSQRT_SF,
AARCH64_BUILTIN_RSQRT_V2DF,
#undef AARCH64_INIT_MEMTAG_BUILTINS_DECL
}
-/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */
+/* Initialize fpsr fpcr getters and setters. */
-void
-aarch64_general_init_builtins (void)
+static void
+aarch64_init_fpsr_fpcr_builtins (void)
{
- tree ftype_set_fpr
+ tree ftype_set
= build_function_type_list (void_type_node, unsigned_type_node, NULL);
- tree ftype_get_fpr
+ tree ftype_get
= build_function_type_list (unsigned_type_node, NULL);
aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR]
= aarch64_general_add_builtin ("__builtin_aarch64_get_fpcr",
- ftype_get_fpr,
+ ftype_get,
AARCH64_BUILTIN_GET_FPCR);
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR]
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr",
- ftype_set_fpr,
+ ftype_set,
AARCH64_BUILTIN_SET_FPCR);
aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR]
= aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr",
- ftype_get_fpr,
+ ftype_get,
AARCH64_BUILTIN_GET_FPSR);
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR]
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr",
- ftype_set_fpr,
+ ftype_set,
AARCH64_BUILTIN_SET_FPSR);
+ ftype_set
+ = build_function_type_list (void_type_node, long_long_unsigned_type_node,
+ NULL);
+ ftype_get
+ = build_function_type_list (long_long_unsigned_type_node, NULL);
+
+ aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR64]
+ = aarch64_general_add_builtin ("__builtin_aarch64_get_fpcr64",
+ ftype_get,
+ AARCH64_BUILTIN_GET_FPCR64);
+ aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR64]
+ = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr64",
+ ftype_set,
+ AARCH64_BUILTIN_SET_FPCR64);
+ aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR64]
+ = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr64",
+ ftype_get,
+ AARCH64_BUILTIN_GET_FPSR64);
+ aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR64]
+ = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr64",
+ ftype_set,
+ AARCH64_BUILTIN_SET_FPSR64);
+}
+
+/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */
+
+void
+aarch64_general_init_builtins (void)
+{
+ aarch64_init_fpsr_fpcr_builtins ();
+
aarch64_init_fp16_types ();
aarch64_init_bf16_types ();
return target;
}
+/* Expand an expression EXP as fpsr or cpsr setter (depending on
+ UNSPEC) using MODE. */
+static void
+aarch64_expand_fpsr_fpcr_setter (int unspec, machine_mode mode, tree exp)
+{
+ tree arg = CALL_EXPR_ARG (exp, 0);
+ rtx op = force_reg (mode, expand_normal (arg));
+ emit_insn (gen_aarch64_set (unspec, mode, op));
+}
+
/* 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. */
int ignore)
{
int icode;
- rtx pat, op0;
+ rtx op0;
tree arg0;
switch (fcode)
{
case AARCH64_BUILTIN_GET_FPCR:
+ emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, SImode, target));
+ return target;
case AARCH64_BUILTIN_SET_FPCR:
+ aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, SImode, exp);
+ return target;
case AARCH64_BUILTIN_GET_FPSR:
+ emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, SImode, target));
+ return target;
case AARCH64_BUILTIN_SET_FPSR:
- if ((fcode == AARCH64_BUILTIN_GET_FPCR)
- || (fcode == AARCH64_BUILTIN_GET_FPSR))
- {
- icode = (fcode == AARCH64_BUILTIN_GET_FPSR) ?
- CODE_FOR_get_fpsr : CODE_FOR_get_fpcr;
- target = gen_reg_rtx (SImode);
- pat = GEN_FCN (icode) (target);
- }
- else
- {
- target = NULL_RTX;
- icode = (fcode == AARCH64_BUILTIN_SET_FPSR) ?
- CODE_FOR_set_fpsr : CODE_FOR_set_fpcr;
- arg0 = CALL_EXPR_ARG (exp, 0);
- op0 = force_reg (SImode, expand_normal (arg0));
- pat = GEN_FCN (icode) (op0);
- }
- emit_insn (pat);
+ aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, SImode, exp);
+ return target;
+ case AARCH64_BUILTIN_GET_FPCR64:
+ emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, DImode, target));
+ return target;
+ case AARCH64_BUILTIN_SET_FPCR64:
+ aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, DImode, exp);
+ return target;
+ case AARCH64_BUILTIN_GET_FPSR64:
+ emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, DImode, target));
+ return target;
+ case AARCH64_BUILTIN_SET_FPSR64:
+ aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, DImode, exp);
return target;
-
case AARCH64_PAUTH_BUILTIN_AUTIA1716:
case AARCH64_PAUTH_BUILTIN_PACIA1716:
case AARCH64_PAUTH_BUILTIN_AUTIB1716:
[(set_attr "length" "12")
(set_attr "type" "multiple")])
-;; Write Floating-point Control Register.
-(define_insn "set_fpcr"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
+;; Write into the Floating-point Status or Control Register.
+(define_insn "@aarch64_set_<fpscr_name><GPI:mode>"
+ [(unspec_volatile [(match_operand:GPI 0 "register_operand" "r")] SET_FPSCR)]
""
- "msr\\tfpcr, %0"
+ "msr\\t<fpscr_name>, %0"
[(set_attr "type" "mrs")])
-;; Read Floating-point Control Register.
-(define_insn "get_fpcr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
- ""
- "mrs\\t%0, fpcr"
- [(set_attr "type" "mrs")])
-
-;; Write Floating-point Status Register.
-(define_insn "set_fpsr"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
- ""
- "msr\\tfpsr, %0"
- [(set_attr "type" "mrs")])
-
-;; Read Floating-point Status Register.
-(define_insn "get_fpsr"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
+;; Read into the Floating-point Status or Control Register.
+(define_insn "@aarch64_get_<fpscr_name><GPI:mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))]
""
- "mrs\\t%0, fpsr"
+ "mrs\\t%0, <fpscr_name>"
[(set_attr "type" "mrs")])
-
;; Define the subtract-one-and-jump insns so loop.c
;; knows what to generate.
(define_expand "doloop_end"