aarch64: Add 64 bit setter getter fpsr fpcr
gcc/ChangeLog * config/aarch64/aarch64-builtins.c (aarch64_builtins): Add enums for 64bits fpsr/fpcr getter setters builtin variants. (aarch64_init_fpsr_fpcr_builtins): New function. (aarch64_general_init_builtins): Modify to make use of the later. (aarch64_expand_fpsr_fpcr_setter): New function. (aarch64_general_expand_builtin): Modify to make use of the later. * config/aarch64/aarch64.md (@aarch64_set_<fpscr_name><GPI:mode>) (@aarch64_get_<fpscr_name><GPI:mode>): New patterns replacing and generalizing 'get_fpcr', 'set_fpsr'. * config/aarch64/iterators.md (GET_FPSCR, SET_FPSCR): New int iterators. (fpscr_name): New int attribute. * doc/extend.texi (__builtin_aarch64_get_fpcr64) (__builtin_aarch64_set_fpcr64, __builtin_aarch64_get_fpsr64) (__builtin_aarch64_set_fpsr64): Add into AArch64 Built-in Functions. gcc/testsuite/ChangeLog * gcc.target/aarch64/get_fpcr64_1.c: New test. * gcc.target/aarch64/set_fpcr64_1.c: New test. * gcc.target/aarch64/get_fpsr64_1.c: New test. * gcc.target/aarch64/set_fpsr64_1.c: New test.
This commit is contained in:
parent
685d8dafb4
commit
0d7e5fa655
@ -450,6 +450,11 @@ enum aarch64_builtins
|
||||
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,
|
||||
@ -1247,32 +1252,63 @@ aarch64_init_memtag_builtins (void)
|
||||
#undef AARCH64_INIT_MEMTAG_BUILTINS_DECL
|
||||
}
|
||||
|
||||
/* Initialize fpsr fpcr getters and setters. */
|
||||
|
||||
static void
|
||||
aarch64_init_fpsr_fpcr_builtins (void)
|
||||
{
|
||||
tree ftype_set
|
||||
= build_function_type_list (void_type_node, unsigned_type_node, NULL);
|
||||
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,
|
||||
AARCH64_BUILTIN_GET_FPCR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr",
|
||||
ftype_set,
|
||||
AARCH64_BUILTIN_SET_FPCR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr",
|
||||
ftype_get,
|
||||
AARCH64_BUILTIN_GET_FPSR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr",
|
||||
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)
|
||||
{
|
||||
tree ftype_set_fpr
|
||||
= build_function_type_list (void_type_node, unsigned_type_node, NULL);
|
||||
tree ftype_get_fpr
|
||||
= 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,
|
||||
AARCH64_BUILTIN_GET_FPCR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr",
|
||||
ftype_set_fpr,
|
||||
AARCH64_BUILTIN_SET_FPCR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr",
|
||||
ftype_get_fpr,
|
||||
AARCH64_BUILTIN_GET_FPSR);
|
||||
aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR]
|
||||
= aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr",
|
||||
ftype_set_fpr,
|
||||
AARCH64_BUILTIN_SET_FPSR);
|
||||
aarch64_init_fpsr_fpcr_builtins ();
|
||||
|
||||
aarch64_init_fp16_types ();
|
||||
|
||||
@ -1878,6 +1914,16 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
|
||||
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. */
|
||||
@ -1886,35 +1932,35 @@ aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
|
||||
int ignore)
|
||||
{
|
||||
int icode;
|
||||
rtx pat, op0;
|
||||
rtx op0;
|
||||
tree arg0;
|
||||
|
||||
switch (fcode)
|
||||
{
|
||||
case AARCH64_BUILTIN_GET_FPCR:
|
||||
case AARCH64_BUILTIN_SET_FPCR:
|
||||
case AARCH64_BUILTIN_GET_FPSR:
|
||||
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);
|
||||
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:
|
||||
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:
|
||||
|
@ -7230,37 +7230,21 @@
|
||||
[(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))]
|
||||
;; 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, fpcr"
|
||||
"mrs\\t%0, <fpscr_name>"
|
||||
[(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))]
|
||||
""
|
||||
"mrs\\t%0, fpsr"
|
||||
[(set_attr "type" "mrs")])
|
||||
|
||||
|
||||
;; Define the subtract-one-and-jump insns so loop.c
|
||||
;; knows what to generate.
|
||||
(define_expand "doloop_end"
|
||||
|
@ -3453,3 +3453,17 @@
|
||||
|
||||
(define_int_attr unspec [(UNSPEC_WHILERW "UNSPEC_WHILERW")
|
||||
(UNSPEC_WHILEWR "UNSPEC_WHILEWR")])
|
||||
|
||||
;; Iterators and attributes for fpcr fpsr getter setters
|
||||
|
||||
(define_int_iterator GET_FPSCR
|
||||
[UNSPECV_GET_FPSR UNSPECV_GET_FPCR])
|
||||
|
||||
(define_int_iterator SET_FPSCR
|
||||
[UNSPECV_SET_FPSR UNSPECV_SET_FPCR])
|
||||
|
||||
(define_int_attr fpscr_name
|
||||
[(UNSPECV_GET_FPSR "fpsr")
|
||||
(UNSPECV_SET_FPSR "fpsr")
|
||||
(UNSPECV_GET_FPCR "fpcr")
|
||||
(UNSPECV_SET_FPCR "fpcr")])
|
||||
|
@ -13881,6 +13881,11 @@ unsigned int __builtin_aarch64_get_fpcr ()
|
||||
void __builtin_aarch64_set_fpcr (unsigned int)
|
||||
unsigned int __builtin_aarch64_get_fpsr ()
|
||||
void __builtin_aarch64_set_fpsr (unsigned int)
|
||||
|
||||
unsigned long long __builtin_aarch64_get_fpcr64 ()
|
||||
void __builtin_aarch64_set_fpcr64 (unsigned long long)
|
||||
unsigned long long __builtin_aarch64_get_fpsr64 ()
|
||||
void __builtin_aarch64_set_fpsr64 (unsigned long long)
|
||||
@end smallexample
|
||||
|
||||
@node Alpha Built-in Functions
|
||||
|
10
gcc/testsuite/gcc.target/aarch64/get_fpcr64_1.c
Normal file
10
gcc/testsuite/gcc.target/aarch64/get_fpcr64_1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
long long unsigned
|
||||
get_fpcr64 ()
|
||||
{
|
||||
return __builtin_aarch64_get_fpcr64 ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\tmrs\tx0, fpcr\n} 1 } } */
|
10
gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.c
Normal file
10
gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
long long unsigned
|
||||
get_fpsr64 ()
|
||||
{
|
||||
return __builtin_aarch64_get_fpsr64 ();
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\tmrs\tx0, fpsr\n} 1 } } */
|
10
gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.c
Normal file
10
gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
void
|
||||
set_fpcr64 (long long unsigned x)
|
||||
{
|
||||
return __builtin_aarch64_set_fpcr64 (x);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\tmsr\tfpcr, x0\n} 1 } } */
|
10
gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.c
Normal file
10
gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.c
Normal file
@ -0,0 +1,10 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O2" } */
|
||||
|
||||
void
|
||||
set_fpsr64 (long long unsigned x)
|
||||
{
|
||||
return __builtin_aarch64_set_fpsr64 (x);
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-times {\tmsr\tfpsr, x0\n} 1 } } */
|
Loading…
Reference in New Issue
Block a user