[NDS32] Add intrinsic functions for FPU.
authorMonk Chiang <sh.chiang04@gmail.com>
Sat, 7 Apr 2018 05:40:07 +0000 (05:40 +0000)
committerChung-Ju Wu <jasonwucj@gcc.gnu.org>
Sat, 7 Apr 2018 05:40:07 +0000 (05:40 +0000)
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
gcc/config/nds32/constants.md
gcc/config/nds32/nds32-intrinsic.c
gcc/config/nds32/nds32-intrinsic.md
gcc/config/nds32/nds32.h
gcc/config/nds32/nds32_intrinsic.h

index 260baebd2a81dbd7e29171d165b588d16ecdd580..bb30f3d4e0b04119cd7bc18bb71995354d486251 100644 (file)
@@ -1,3 +1,23 @@
+2018-04-07  Monk Chiang  <sh.chiang04@gmail.com>
+
+       * 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  <sh.chiang04@gmail.com>
 
        * config/nds32/nds32.c (nds32_intrinsic_register_names): Add more
index 7c706eb7da033fbfce778ffdf537d8a99768e683..1a0e880dc43c2c59530259b6bf7c25f12b630dd5 100644 (file)
@@ -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
index 636b1d1139fe2f9546169fdae6dce83b321ae66e..c5435bb9dd41bee9af2eaa73504168333bfb0b12 100644 (file)
@@ -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);
index 5a07f89fa55bd02655276158a9b7766890bea035..59aad349dc386712d9851c2b0b4e572f03db66ed 100644 (file)
    (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.
index 934fe03ba17de7695a2629c773668d4faf04d8a3..7ec0f7c2ba148a5aec201f2adfaf96c8134c65c6 100644 (file)
@@ -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,
index 5656ce5a07d49c94633bd6da5bf478388c870f41..523e7f571edf72e8f0a7f5bcc9c35b5e1e8ceca1 100644 (file)
@@ -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 */