diff mbox

[committed] rs6000 builtins for FPSCR

Message ID CAGWvnyk8qmPnk=E6EM35pHmKmALv+vB4+OCxBzUufjtQgOxCOw@mail.gmail.com
State New
Headers show

Commit Message

David Edelsohn Jan. 11, 2014, 6:41 p.m. UTC
This patch adds builtins to load and store the PowerPC floating point
status and control register.

        * config/rs6000/rs6000.c (rs6000_expand_mtfsf_builtin): New.
        (rs6000_expand_builtin): Handle mffs and mtfsf.
        (rs6000_init_builtins): Define mffs and mtfsf.
        * config/rs6000/rs6000.md (UNSPECV_MFFS, UNSPECV_MTFSF): New constants.
        (rs6000_mffs): New pattern.
        (rs6000_mtfsf): New pattern.

 ;; a GPR.  The addis instruction must be adjacent to the load, and use the same
 ;; register that is being loaded.  The fused ops must be physically adjacent.
diff mbox

Patch

Index: rs6000-builtin.def
===================================================================
--- rs6000-builtin.def  (revision 206552)
+++ rs6000-builtin.def  (working copy)
@@ -1752,6 +1752,14 @@ 
 BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb",
              RS6000_BTM_ALWAYS, RS6000_BTC_MISC)

+BU_SPECIAL_X (RS6000_BUILTIN_MFFS, "__builtin_mffs",
+             RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+
+RS6000_BUILTIN_X (RS6000_BUILTIN_MTFSF, "__builtin_mtfsf",
+                 RS6000_BTM_ALWAYS,
+                 RS6000_BTC_MISC | RS6000_BTC_UNARY | RS6000_BTC_VOID,
+                 CODE_FOR_rs6000_mtfsf)
+
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
              RS6000_BTC_MISC)
Index: rs6000.c
===================================================================
--- rs6000.c    (revision 206552)
+++ rs6000.c    (working copy)
@@ -11469,6 +11470,48 @@ 


 static rtx
+rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp, rtx target)
+{
+  rtx pat;
+  tree arg0 = CALL_EXPR_ARG (exp, 0);
+  tree arg1 = CALL_EXPR_ARG (exp, 1);
+  rtx op0 = expand_normal (arg0);
+  rtx op1 = expand_normal (arg1);
+  enum machine_mode mode0 = insn_data[icode].operand[0].mode;
+  enum machine_mode mode1 = insn_data[icode].operand[1].mode;
+
+  if (icode == CODE_FOR_nothing)
+    /* Builtin not supported on this processor.  */
+    return 0;
+
+  /* If we got invalid arguments bail out before generating bad rtl.  */
+  if (arg0 == error_mark_node || arg1 == error_mark_node)
+    return const0_rtx;
+
+  if (GET_CODE (op0) != CONST_INT
+      || INTVAL (op0) > 255
+      || INTVAL (op0) < 0)
+    {
+      error ("argument 1 must be an 8-bit field value");
+      return const0_rtx;
+    }
+
+  if (! (*insn_data[icode].operand[0].predicate) (op0, mode0))
+    op0 = copy_to_mode_reg (mode0, op0);
+
+  if (! (*insn_data[icode].operand[1].predicate) (op1, mode1))
+    op1 = copy_to_mode_reg (mode1, op1);
+
+  pat = GEN_FCN (icode) (op0, op1);
+  if (! pat)
+    return const0_rtx;
+  emit_insn (pat);
+
+  return NULL_RTX;
+}
+
+
+static rtx
 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
 {
   rtx pat;
@@ -13277,6 +13320,12 @@ 
                                            : CODE_FOR_rs6000_mftb_si),
                                           target);

+    case RS6000_BUILTIN_MFFS:
+      return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_mffs, target);
+
+    case RS6000_BUILTIN_MTFSF:
+      return rs6000_expand_mtfsf_builtin (CODE_FOR_rs6000_mtfsf, exp, target);
+
     case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
     case ALTIVEC_BUILTIN_MASK_FOR_STORE:
       {
@@ -13584,6 +13633,14 @@ 
                                      NULL_TREE);
   def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB);

+  ftype = build_function_type_list (double_type_node, NULL_TREE);
+  def_builtin ("__builtin_mffs", ftype, RS6000_BUILTIN_MFFS);
+
+  ftype = build_function_type_list (void_type_node,
+                                   intSI_type_node, double_type_node,
+                                   NULL_TREE);
+  def_builtin ("__builtin_mtfsf", ftype, RS6000_BUILTIN_MTFSF);
+
 #if TARGET_XCOFF
   /* AIX libm provides clog as __clog.  */
   if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
Index: rs6000.md
===================================================================
--- rs6000.md   (revision 206552)
+++ rs6000.md   (working copy)
@@ -140,6 +140,8 @@ 
    UNSPECV_ISYNC               ; isync instruction
    UNSPECV_MFTB                        ; move from time base
    UNSPECV_NLGR                        ; non-local goto receiver
+   UNSPECV_MFFS                        ; Move from FPSCR
+   UNSPECV_MTFSF               ; Move to FPSCR Fields
   ])


@@ -15587,6 +15589,20 @@ 
 })



+(define_insn "rs6000_mffs"
+  [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
+    (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "mffs %0")
+
+(define_insn "rs6000_mtfsf"
+  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
+             (match_operand:DF 1 "gpc_reg_operand" "d")]
+            UNSPECV_MTFSF)]
+  "TARGET_HARD_FLOAT && TARGET_FPRS"
+  "mtfsf %0,%1")
+
+

 ;; Power8 fusion support for fusing an addis instruction with a D-form load of