From 0bb4423d43b70344c2811ebec37f3b6a9e678c80 Mon Sep 17 00:00:00 2001 From: Monk Chiang Date: Sat, 7 Apr 2018 05:40:07 +0000 Subject: [PATCH] [NDS32] Add intrinsic functions for FPU. gcc/ * config/nds32/constants.md (unspec_volatile_element): Add UNSPEC_VOLATILE_FMFCSR, UNSPEC_VOLATILE_FMTCSR and UNSPEC_VOLATILE_FMFCFG. * config/nds32/nds32-intrinsic.c (bdesc_noarg): New builtin description for fmfcfg and fmfcsr. (bdesc_1arg): Add fmtcsr. (bdesc_2arg): Add fcpynss, fcpyss, fcpynsd and fcpysd. (nds32_expand_builtin_impl): Deal with FPU intrinsic functions. * config/nds32/nds32-intrinsic.md (unspec_fcpynsd, unspec_fcpysd, unspec_fcpynss, unspec_fcpysd, unspec_fcpyss, unspec_fmfcsr, unspec_fmfcfg): New patterns. * config/nds32/nds32.h (nds32_builtins): Add NDS32_BUILTIN_FMFCFG, NDS32_BUILTIN_FMFCSR, NDS32_BUILTIN_FMTCSR, NDS32_BUILTIN_FCPYNSS, NDS32_BUILTIN_FCPYSS,NDS32_BUILTIN_FCPYNSD and NDS32_BUILTIN_FCPYSD. * config/nds32/nds32_intrinsic.h (__nds32__fcpynsd, __nds32__fcpynss, __nds32__fcpysd, __nds32__fcpyss, __nds32__fmfcsr, __nds32__fmtcsr, __nds32__fmfcfg): Define. From-SVN: r259203 --- gcc/ChangeLog | 20 +++++++++++ gcc/config/nds32/constants.md | 3 ++ gcc/config/nds32/nds32-intrinsic.c | 51 ++++++++++++++++++++++++++++ gcc/config/nds32/nds32-intrinsic.md | 68 +++++++++++++++++++++++++++++++++++++ gcc/config/nds32/nds32.h | 7 ++++ gcc/config/nds32/nds32_intrinsic.h | 15 ++++++++ 6 files changed, 164 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 260baeb..bb30f3d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,25 @@ 2018-04-07 Monk Chiang + * config/nds32/constants.md (unspec_volatile_element): Add + UNSPEC_VOLATILE_FMFCSR, UNSPEC_VOLATILE_FMTCSR and + UNSPEC_VOLATILE_FMFCFG. + * config/nds32/nds32-intrinsic.c (bdesc_noarg): New builtin + description for fmfcfg and fmfcsr. + (bdesc_1arg): Add fmtcsr. + (bdesc_2arg): Add fcpynss, fcpyss, fcpynsd and fcpysd. + (nds32_expand_builtin_impl): Deal with FPU intrinsic functions. + * config/nds32/nds32-intrinsic.md (unspec_fcpynsd, unspec_fcpysd, + unspec_fcpynss, unspec_fcpysd, unspec_fcpyss, unspec_fmfcsr, + unspec_fmfcfg): New patterns. + * config/nds32/nds32.h (nds32_builtins): Add NDS32_BUILTIN_FMFCFG, + NDS32_BUILTIN_FMFCSR, NDS32_BUILTIN_FMTCSR, NDS32_BUILTIN_FCPYNSS, + NDS32_BUILTIN_FCPYSS,NDS32_BUILTIN_FCPYNSD and NDS32_BUILTIN_FCPYSD. + * config/nds32/nds32_intrinsic.h (__nds32__fcpynsd, __nds32__fcpynss, + __nds32__fcpysd, __nds32__fcpyss, __nds32__fmfcsr, __nds32__fmtcsr, + __nds32__fmfcfg): Define. + +2018-04-07 Monk Chiang + * config/nds32/nds32.c (nds32_intrinsic_register_names): Add more intrinsic register names. * config/nds32/nds32_intrinsic.h (nds32_intrinsic_registers): Add more diff --git a/gcc/config/nds32/constants.md b/gcc/config/nds32/constants.md index 7c706eb..1a0e880 100644 --- a/gcc/config/nds32/constants.md +++ b/gcc/config/nds32/constants.md @@ -58,6 +58,9 @@ UNSPEC_VOLATILE_MTUSR UNSPEC_VOLATILE_SETGIE_EN UNSPEC_VOLATILE_SETGIE_DIS + UNSPEC_VOLATILE_FMFCSR + UNSPEC_VOLATILE_FMTCSR + UNSPEC_VOLATILE_FMFCFG UNSPEC_VOLATILE_RELAX_GROUP UNSPEC_VOLATILE_POP25_RETURN diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c index 636b1d1..c5435bb 100644 --- a/gcc/config/nds32/nds32-intrinsic.c +++ b/gcc/config/nds32/nds32-intrinsic.c @@ -238,6 +238,13 @@ struct builtin_description { CODE_FOR_##code, "__nds32__" string, \ NDS32_BUILTIN_##builtin, false }, +/* Intrinsics that no argument, and that return value. */ +static struct builtin_description bdesc_noarg[] = +{ + NDS32_BUILTIN(unspec_fmfcfg, "fmfcfg", FMFCFG) + NDS32_BUILTIN(unspec_fmfcsr, "fmfcsr", FMFCSR) +}; + /* Intrinsics that take just one argument. */ static struct builtin_description bdesc_1arg[] = { @@ -245,6 +252,7 @@ static struct builtin_description bdesc_1arg[] = NDS32_BUILTIN(unaligned_loadsi, "unaligned_load_w", UALOAD_W) NDS32_BUILTIN(unaligned_loaddi, "unaligned_load_dw", UALOAD_DW) NDS32_NO_TARGET_BUILTIN(unspec_volatile_isync, "isync", ISYNC) + NDS32_NO_TARGET_BUILTIN(unspec_fmtcsr, "fmtcsr", FMTCSR) }; /* Intrinsics that take just one argument. and the argument is immediate. */ @@ -257,6 +265,10 @@ static struct builtin_description bdesc_1argimm[] = /* Intrinsics that take two arguments. */ static struct builtin_description bdesc_2arg[] = { + NDS32_BUILTIN(unspec_fcpynss, "fcpynss", FCPYNSS) + NDS32_BUILTIN(unspec_fcpyss, "fcpyss", FCPYSS) + NDS32_BUILTIN(unspec_fcpynsd, "fcpynsd", FCPYNSD) + NDS32_BUILTIN(unspec_fcpysd, "fcpysd", FCPYSD) NDS32_BUILTIN(unspec_ffb, "ffb", FFB) NDS32_BUILTIN(unspec_ffmism, "ffmsim", FFMISM) NDS32_BUILTIN(unspec_flmism, "flmism", FLMISM) @@ -282,6 +294,32 @@ nds32_expand_builtin_impl (tree exp, switch (fcode) { + /* FPU Register Transfer. */ + case NDS32_BUILTIN_FMFCFG: + case NDS32_BUILTIN_FMFCSR: + case NDS32_BUILTIN_FMTCSR: + case NDS32_BUILTIN_FCPYNSS: + case NDS32_BUILTIN_FCPYSS: + /* Both v3s and v3f toolchains define TARGET_FPU_SINGLE. */ + if (!TARGET_FPU_SINGLE) + { + error ("this builtin function is only available " + "on the v3s or v3f toolchain"); + return NULL_RTX; + } + break; + + /* FPU Register Transfer. */ + case NDS32_BUILTIN_FCPYNSD: + case NDS32_BUILTIN_FCPYSD: + /* Only v3f toolchain defines TARGET_FPU_DOUBLE. */ + if (!TARGET_FPU_DOUBLE) + { + error ("this builtin function is only available " + "on the v3f toolchain"); + return NULL_RTX; + } + break; /* String Extension */ case NDS32_BUILTIN_FFB: case NDS32_BUILTIN_FFMISM: @@ -314,6 +352,10 @@ nds32_expand_builtin_impl (tree exp, } /* Expand groups of builtins. */ + for (i = 0, d = bdesc_noarg; i < ARRAY_SIZE (bdesc_noarg); i++, d++) + if (d->code == fcode) + return nds32_expand_noarg_builtin (d->icode, target); + for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++) if (d->code == fcode) return nds32_expand_unop_builtin (d->icode, exp, target, d->return_p); @@ -396,6 +438,15 @@ nds32_init_builtins_impl (void) ADD_NDS32_BUILTIN2 ("mtsr", void, unsigned, integer, MTSR); ADD_NDS32_BUILTIN2 ("mtusr", void, unsigned, integer, MTUSR); + /* FPU Register Transfer. */ + ADD_NDS32_BUILTIN0 ("fmfcsr", unsigned, FMFCSR); + ADD_NDS32_BUILTIN1 ("fmtcsr", void, unsigned, FMTCSR); + ADD_NDS32_BUILTIN0 ("fmfcfg", unsigned, FMFCFG); + ADD_NDS32_BUILTIN2 ("fcpyss", float, float, float, FCPYSS); + ADD_NDS32_BUILTIN2 ("fcpynss", float, float, float, FCPYNSS); + ADD_NDS32_BUILTIN2 ("fcpysd", double, double, double, FCPYSD); + ADD_NDS32_BUILTIN2 ("fcpynsd", double, double, double, FCPYNSD); + /* Interrupt. */ ADD_NDS32_BUILTIN0 ("setgie_en", void, SETGIE_EN); ADD_NDS32_BUILTIN0 ("setgie_dis", void, SETGIE_DIS); diff --git a/gcc/config/nds32/nds32-intrinsic.md b/gcc/config/nds32/nds32-intrinsic.md index 5a07f89..59aad34 100644 --- a/gcc/config/nds32/nds32-intrinsic.md +++ b/gcc/config/nds32/nds32-intrinsic.md @@ -58,6 +58,74 @@ (set_attr "length" "4")] ) +;; FPU Register Transfer. + +(define_insn "unspec_fcpynsd" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYNSD))] + "" + "fcpynsd\t%0, %1, %2" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fcpynss" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYNSS))] + "" + "fcpynss\t%0, %1, %2" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fcpysd" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] UNSPEC_FCPYSD))] + "" + "fcpysd\t%0, %1, %2" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fcpyss" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] UNSPEC_FCPYSS))] + "" + "fcpyss\t%0, %1, %2" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fmfcsr" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCSR))] + "" + "fmfcsr\t%0" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fmtcsr" + [(unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")] UNSPEC_VOLATILE_FMTCSR)] + "" + "fmtcsr\t%0" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + +(define_insn "unspec_fmfcfg" + [(set (match_operand:SI 0 "register_operand" "=r") + (unspec_volatile:SI [(const_int 0)] UNSPEC_VOLATILE_FMFCFG))] + "" + "fmfcfg\t%0" + [(set_attr "type" "misc") + (set_attr "length" "4")] +) + ;; ------------------------------------------------------------------------ ;; Interrupt Instructions. diff --git a/gcc/config/nds32/nds32.h b/gcc/config/nds32/nds32.h index 934fe03..7ec0f7c 100644 --- a/gcc/config/nds32/nds32.h +++ b/gcc/config/nds32/nds32.h @@ -442,6 +442,13 @@ enum nds32_builtins NDS32_BUILTIN_MTUSR, NDS32_BUILTIN_SETGIE_EN, NDS32_BUILTIN_SETGIE_DIS, + NDS32_BUILTIN_FMFCFG, + NDS32_BUILTIN_FMFCSR, + NDS32_BUILTIN_FMTCSR, + NDS32_BUILTIN_FCPYNSS, + NDS32_BUILTIN_FCPYSS, + NDS32_BUILTIN_FCPYNSD, + NDS32_BUILTIN_FCPYSD, NDS32_BUILTIN_FFB, NDS32_BUILTIN_FFMISM, NDS32_BUILTIN_FLMISM, diff --git a/gcc/config/nds32/nds32_intrinsic.h b/gcc/config/nds32/nds32_intrinsic.h index 5656ce5..523e7f5 100644 --- a/gcc/config/nds32/nds32_intrinsic.h +++ b/gcc/config/nds32/nds32_intrinsic.h @@ -345,4 +345,19 @@ enum nds32_intrinsic_registers #define NDS32_USR_IFC_LP __NDS32_REG_IFC_LP__ #define NDS32_USR_ITB __NDS32_REG_ITB__ +#define __nds32__fcpynsd(a, b) \ + (__builtin_nds32_fcpynsd ((a), (b))) +#define __nds32__fcpynss(a, b) \ + (__builtin_nds32_fcpynss ((a), (b))) +#define __nds32__fcpysd(a, b) \ + (__builtin_nds32_fcpysd ((a), (b))) +#define __nds32__fcpyss(a, b) \ + (__builtin_nds32_fcpyss ((a), (b))) +#define __nds32__fmfcsr() \ + (__builtin_nds32_fmfcsr()) +#define __nds32__fmtcsr(fpcsr) \ + (__builtin_nds32_fmtcsr ((fpcsr))) +#define __nds32__fmfcfg() \ + (__builtin_nds32_fmfcfg()) + #endif /* nds32_intrinsic.h */ -- 2.7.4