rs6000: Define a pattern for mffscrni. If the RN is a constant, it can call gen_rs60...
authorHaochen Gui <guihaoc@gcc.gnu.org>
Fri, 7 Jan 2022 06:20:44 +0000 (14:20 +0800)
committerHaochen Gui <guihaoc@gcc.gnu.org>
Fri, 7 Jan 2022 06:36:42 +0000 (14:36 +0800)
gcc/
* config/rs6000/rs6000.md (rs6000_mffscrni): Define.
(rs6000_set_fpscr_rn): Change the type of operand[0] from DI to SI.
Call gen_rs6000_mffscrni when operand[0] is a const_0_to_3_operand.

gcc/testsuite/
* gcc.target/powerpc/mffscrni_p9.c: New testcase for mffscrni.
* gcc.target/powerpc/test_fpscr_rn_builtin.c: Test mffscrn and mffscrni
separately.

gcc/config/rs6000/rs6000.md
gcc/testsuite/gcc.target/powerpc/mffscrni_p9.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/test_fpscr_rn_builtin.c

index 1582dda..6ecb0bd 100644 (file)
    "mffscrn %0,%1"
   [(set_attr "type" "fp")])
 
+(define_insn "rs6000_mffscrni"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+       (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")]
+                           UNSPECV_MFFSCRN))]
+   "TARGET_P9_MISC"
+   "mffscrni %0,%1"
+  [(set_attr "type" "fp")])
+
 (define_insn "rs6000_mffscdrn"
   [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
   [(set_attr "type" "fp")])
 
 (define_expand "rs6000_set_fpscr_rn"
- [(match_operand:DI 0 "reg_or_cint_operand")]
+ [(match_operand:SI 0 "reg_or_cint_operand")]
   "TARGET_HARD_FLOAT"
 {
   rtx tmp_df = gen_reg_rtx (DFmode);
      new rounding mode bits from operands[0][62:63] into FPSCR[62:63].  */
   if (TARGET_P9_MISC)
     {
-      rtx src_df = force_reg (DImode, operands[0]);
-      src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
-      emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
+      if (const_0_to_3_operand (operands[0], VOIDmode))
+       emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0]));
+      else
+       {
+         rtx op0 = convert_to_mode (DImode, operands[0], false);
+         rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0);
+         emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
+       }
       DONE;
     }
 
       rtx tmp_di = gen_reg_rtx (DImode);
 
       /* Extract new RN mode from operand.  */
-      emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
+      rtx op0 = convert_to_mode (DImode, operands[0], false);
+      emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3)));
 
       /* Insert new RN mode into FSCPR.  */
       emit_insn (gen_rs6000_mffs (tmp_df));
diff --git a/gcc/testsuite/gcc.target/powerpc/mffscrni_p9.c b/gcc/testsuite/gcc.target/powerpc/mffscrni_p9.c
new file mode 100644 (file)
index 0000000..d97c6db
--- /dev/null
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mdejagnu-cpu=power9" } */
+/* { dg-final { scan-assembler-times {\mmffscrni\M} 1 } } */
+
+void foo ()
+{
+  int val = 2;
+  __builtin_set_fpscr_rn (val);
+}
index 0d0d3f0..04707ad 100644 (file)
@@ -8,6 +8,10 @@
 #define RN_MASK  0x3LL             /* RN field mask */
 
 void abort (void);
+void __attribute__ ((noipa)) wrap_set_fpscr_rn (int val)
+{
+  __builtin_set_fpscr_rn (val);
+}
 
 int main ()
 {
@@ -43,7 +47,8 @@ int main ()
     }            
 
   /* Test float rounding mode builtin with const value argument.  */
-  __builtin_set_fpscr_rn(3);
+  val = 3;
+  __builtin_set_fpscr_rn (val);
   conv_val.d = __builtin_mffs();
   ll_value = conv_val.ll & RN_MASK;
 
@@ -58,7 +63,7 @@ int main ()
     }            
 
   val = 2;
-  __builtin_set_fpscr_rn(val);
+  __builtin_set_fpscr_rn (val);
   conv_val.d = __builtin_mffs();
   ll_value = conv_val.ll & RN_MASK;
 
@@ -74,7 +79,7 @@ int main ()
 
   /* Reset to 0 for testing */
   val = 0;
-  __builtin_set_fpscr_rn(val);
+  __builtin_set_fpscr_rn (val);
 
   __builtin_mtfsb1(31);
   conv_val.d = __builtin_mffs();
@@ -157,7 +162,7 @@ int main ()
 
   /* Test builtin float rounding mode with variable as argument.  */
   val = 0;
-  __builtin_set_fpscr_rn(val);
+  wrap_set_fpscr_rn (val);
   conv_val.d = __builtin_mffs();
   ll_value = conv_val.ll & RN_MASK;
 
@@ -172,7 +177,7 @@ int main ()
     }            
 
   val = 3;
-  __builtin_set_fpscr_rn(val);
+  wrap_set_fpscr_rn (val);
   conv_val.d = __builtin_mffs();
   ll_value = conv_val.ll & RN_MASK;