2012-09-19 Tulio Magno Quites Machado Filho <tuliom@linux.vnet.ibm.com>
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Sep 2012 19:05:34 +0000 (19:05 +0000)
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 19 Sep 2012 19:05:34 +0000 (19:05 +0000)
        * config/rs6000/rs6000-builtin.def: Add __builtin_ppc_get_timebase
        and __builtin_ppc_mftb.
        * config/rs6000/rs6000.c (rs6000_expand_zeroop_builtin): New
        function to expand an expression that calls a built-in without
        arguments.
        (rs6000_expand_builtin): Add __builtin_ppc_get_timebase and
        __builtin_ppc_mftb.
        (rs6000_init_builtins): Likewise.
        * config/rs6000/rs6000.md (rs6000_get_timebase): New pattern.
        (rs6000_get_timebase_ppc32): New pattern.
        (rs6000_mftb_<mode>): New pattern.

        * doc/extend.texi (PowerPC Built-in Functions): New section.
        (PowerPC AltiVec/VSX Built-in Functions):
        Move some built-ins unrelated to Altivec/VSX to the new section.

2012-09-19  David Edelsohn  <dje.gcc@gmail.com>

        * rs6000.md (mac*): Remove extra spaces.
        (mulhw*): Same.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@191491 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/doc/extend.texi

index acdf3d6..3782c7c 100644 (file)
@@ -1,3 +1,26 @@
+2012-09-19  Tulio Magno Quites Machado Filho  <tuliom@linux.vnet.ibm.com>
+
+       * config/rs6000/rs6000-builtin.def: Add __builtin_ppc_get_timebase
+       and __builtin_ppc_mftb.
+       * config/rs6000/rs6000.c (rs6000_expand_zeroop_builtin): New
+       function to expand an expression that calls a built-in without
+       arguments.
+       (rs6000_expand_builtin): Add __builtin_ppc_get_timebase and
+       __builtin_ppc_mftb.
+       (rs6000_init_builtins): Likewise.
+       * config/rs6000/rs6000.md (rs6000_get_timebase): New pattern.
+       (rs6000_get_timebase_ppc32): New pattern.
+       (rs6000_mftb_<mode>): New pattern.
+
+       * doc/extend.texi (PowerPC Built-in Functions): New section.
+       (PowerPC AltiVec/VSX Built-in Functions):
+       Move some built-ins unrelated to Altivec/VSX to the new section.
+
+2012-09-19  David Edelsohn  <dje.gcc@gmail.com>
+
+       * rs6000.md (mac*): Remove extra spaces.
+       (mulhw*): Same.
+
 2012-09-19  Oleg Endo  <olegendo@gcc.gnu.org>
 
        PR target/54089
index c8f8f86..9fa3a0f 100644 (file)
@@ -1429,6 +1429,12 @@ BU_SPECIAL_X (RS6000_BUILTIN_RSQRT, "__builtin_rsqrt", RS6000_BTM_FRSQRTE,
 BU_SPECIAL_X (RS6000_BUILTIN_RSQRTF, "__builtin_rsqrtf", RS6000_BTM_FRSQRTES,
              RS6000_BTC_FP)
 
+BU_SPECIAL_X (RS6000_BUILTIN_GET_TB, "__builtin_ppc_get_timebase",
+            RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+
+BU_SPECIAL_X (RS6000_BUILTIN_MFTB, "__builtin_ppc_mftb",
+            RS6000_BTM_ALWAYS, RS6000_BTC_MISC)
+
 /* Darwin CfString builtin.  */
 BU_SPECIAL_X (RS6000_BUILTIN_CFSTRING, "__builtin_cfstring", RS6000_BTM_ALWAYS,
              RS6000_BTC_MISC)
index a880e5e..007473b 100644 (file)
@@ -9748,6 +9748,30 @@ rs6000_overloaded_builtin_p (enum rs6000_builtins fncode)
   return (rs6000_builtin_info[(int)fncode].attr & RS6000_BTC_OVERLOADED) != 0;
 }
 
+/* Expand an expression EXP that calls a builtin without arguments.  */
+static rtx
+rs6000_expand_zeroop_builtin (enum insn_code icode, rtx target)
+{
+  rtx pat;
+  enum machine_mode tmode = insn_data[icode].operand[0].mode;
+
+  if (icode == CODE_FOR_nothing)
+    /* Builtin not supported on this processor.  */
+    return 0;
+
+  if (target == 0
+      || GET_MODE (target) != tmode
+      || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
+    target = gen_reg_rtx (tmode);
+
+  pat = GEN_FCN (icode) (target);
+  if (! pat)
+    return 0;
+  emit_insn (pat);
+
+  return target;
+}
+
 
 static rtx
 rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
@@ -11337,6 +11361,16 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
                                           ? CODE_FOR_bpermd_di
                                           : CODE_FOR_bpermd_si), exp, target);
 
+    case RS6000_BUILTIN_GET_TB:
+      return rs6000_expand_zeroop_builtin (CODE_FOR_rs6000_get_timebase,
+                                          target);
+
+    case RS6000_BUILTIN_MFTB:
+      return rs6000_expand_zeroop_builtin (((TARGET_64BIT)
+                                           ? CODE_FOR_rs6000_mftb_di
+                                           : CODE_FOR_rs6000_mftb_si),
+                                          target);
+
     case ALTIVEC_BUILTIN_MASK_FOR_LOAD:
     case ALTIVEC_BUILTIN_MASK_FOR_STORE:
       {
@@ -11621,6 +11655,18 @@ rs6000_init_builtins (void)
                                 POWER7_BUILTIN_BPERMD, "__builtin_bpermd");
   def_builtin ("__builtin_bpermd", ftype, POWER7_BUILTIN_BPERMD);
 
+  ftype = build_function_type_list (unsigned_intDI_type_node,
+                                   NULL_TREE);
+  def_builtin ("__builtin_ppc_get_timebase", ftype, RS6000_BUILTIN_GET_TB);
+
+  if (TARGET_64BIT)
+    ftype = build_function_type_list (unsigned_intDI_type_node,
+                                     NULL_TREE);
+  else
+    ftype = build_function_type_list (unsigned_intSI_type_node,
+                                     NULL_TREE);
+  def_builtin ("__builtin_ppc_mftb", ftype, RS6000_BUILTIN_MFTB);
+
 #if TARGET_XCOFF
   /* AIX libm provides clog as __clog.  */
   if ((tdecl = builtin_decl_explicit (BUILT_IN_CLOG)) != NULL_TREE)
index 2f3795b..9eb0a37 100644 (file)
    UNSPECV_PROBE_STACK_RANGE   ; probe range of stack addresses
    UNSPECV_EH_RR               ; eh_reg_restore
    UNSPECV_ISYNC               ; isync instruction
+   UNSPECV_MFTB                        ; move from time base
   ])
 
 \f
                            (match_dup 1)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "macchw. %0, %1, %2"
+  "macchw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*macchw"
                            (match_operand:HI 1 "gpc_reg_operand" "r")))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "macchw %0, %1, %2"
+  "macchw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*macchwuc"
                            (match_dup 1)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "macchwu. %0, %1, %2"
+  "macchwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*macchwu"
                            (match_operand:HI 1 "gpc_reg_operand" "r")))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "macchwu %0, %1, %2"
+  "macchwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*machhwc"
                            (const_int 16)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "machhw. %0, %1, %2"
+  "machhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*machhw"
                            (const_int 16)))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "machhw %0, %1, %2"
+  "machhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*machhwuc"
                            (const_int 16)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "machhwu. %0, %1, %2"
+  "machhwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*machhwu"
                            (const_int 16)))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "machhwu %0, %1, %2"
+  "machhwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*maclhwc"
                            (match_dup 2)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "maclhw. %0, %1, %2"
+  "maclhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*maclhw"
                            (match_operand:HI 2 "gpc_reg_operand" "r")))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "maclhw %0, %1, %2"
+  "maclhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*maclhwuc"
                            (match_dup 2)))
                  (match_dup 4)))]
   "TARGET_MULHW"
-  "maclhwu. %0, %1, %2"
+  "maclhwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*maclhwu"
                            (match_operand:HI 2 "gpc_reg_operand" "r")))
                  (match_operand:SI 3 "gpc_reg_operand" "0")))]
   "TARGET_MULHW"
-  "maclhwu %0, %1, %2"
+  "maclhwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmacchwc"
                            (sign_extend:SI
                             (match_dup 1)))))]
   "TARGET_MULHW"
-  "nmacchw. %0, %1, %2"
+  "nmacchw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmacchw"
                            (sign_extend:SI
                             (match_operand:HI 1 "gpc_reg_operand" "r")))))]
   "TARGET_MULHW"
-  "nmacchw %0, %1, %2"
+  "nmacchw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmachhwc"
                             (match_dup 2)
                             (const_int 16)))))]
   "TARGET_MULHW"
-  "nmachhw. %0, %1, %2"
+  "nmachhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmachhw"
                             (match_operand:SI 2 "gpc_reg_operand" "r")
                             (const_int 16)))))]
   "TARGET_MULHW"
-  "nmachhw %0, %1, %2"
+  "nmachhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmaclhwc"
                            (sign_extend:SI
                             (match_dup 2)))))]
   "TARGET_MULHW"
-  "nmaclhw. %0, %1, %2"
+  "nmaclhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*nmaclhw"
                            (sign_extend:SI
                             (match_operand:HI 2 "gpc_reg_operand" "r")))))]
   "TARGET_MULHW"
-  "nmaclhw %0, %1, %2"
+  "nmaclhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulchwc"
                  (sign_extend:SI
                   (match_dup 1))))]
   "TARGET_MULHW"
-  "mulchw. %0, %1, %2"
+  "mulchw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulchw"
                  (sign_extend:SI
                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
   "TARGET_MULHW"
-  "mulchw %0, %1, %2"
+  "mulchw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulchwuc"
                  (zero_extend:SI
                   (match_dup 1))))]
   "TARGET_MULHW"
-  "mulchwu. %0, %1, %2"
+  "mulchwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulchwu"
                  (zero_extend:SI
                   (match_operand:HI 1 "gpc_reg_operand" "r"))))]
   "TARGET_MULHW"
-  "mulchwu %0, %1, %2"
+  "mulchwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulhhwc"
                   (match_dup 2)
                   (const_int 16))))]
   "TARGET_MULHW"
-  "mulhhw. %0, %1, %2"
+  "mulhhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulhhw"
                   (match_operand:SI 2 "gpc_reg_operand" "r")
                   (const_int 16))))]
   "TARGET_MULHW"
-  "mulhhw %0, %1, %2"
+  "mulhhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulhhwuc"
                   (match_dup 2)
                   (const_int 16))))]
   "TARGET_MULHW"
-  "mulhhwu. %0, %1, %2"
+  "mulhhwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mulhhwu"
                   (match_operand:SI 2 "gpc_reg_operand" "r")
                   (const_int 16))))]
   "TARGET_MULHW"
-  "mulhhwu %0, %1, %2"
+  "mulhhwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mullhwc"
                  (sign_extend:SI
                   (match_dup 2))))]
   "TARGET_MULHW"
-  "mullhw. %0, %1, %2"
+  "mullhw. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mullhw"
                  (sign_extend:SI
                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
   "TARGET_MULHW"
-  "mullhw %0, %1, %2"
+  "mullhw %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mullhwuc"
                  (zero_extend:SI
                   (match_dup 2))))]
   "TARGET_MULHW"
-  "mullhwu. %0, %1, %2"
+  "mullhwu. %0,%1,%2"
   [(set_attr "type" "imul3")])
 
 (define_insn "*mullhwu"
                  (zero_extend:SI
                   (match_operand:HI 2 "gpc_reg_operand" "r"))))]
   "TARGET_MULHW"
-  "mullhwu %0, %1, %2"
+  "mullhwu %0,%1,%2"
   [(set_attr "type" "imul3")])
 \f
 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
                     (match_dup 2)]
                    UNSPEC_DLMZB))]
   "TARGET_DLMZB"
-  "dlmzb. %0, %1, %2")
+  "dlmzb. %0,%1,%2")
 
 (define_expand "strlensi"
   [(set (match_operand:SI 0 "gpc_reg_operand" "")
    mt%0 %1
    mt%0 %1
    nop
-   stfs%U0%X0 %1, %0
-   lfs%U1%X1 %0, %1"
+   stfs%U0%X0 %1,%0
+   lfs%U1%X1 %0,%1"
   [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,*,*")
    (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
 
   ""
   "")
 
+(define_expand "rs6000_get_timebase"
+  [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
+  ""
+{
+  if (TARGET_POWERPC64)
+    emit_insn (gen_rs6000_mftb_di (operands[0]));
+  else
+    emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
+  DONE;
+})
+
+(define_insn "rs6000_get_timebase_ppc32"
+  [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
+        (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
+   (clobber (match_scratch:SI 1 "=r"))
+   (clobber (match_scratch:CC 2 "=y"))]
+  "!TARGET_POWERPC64"
+{
+  if (WORDS_BIG_ENDIAN)
+    if (TARGET_MFCRF)
+      {
+        return "mfspr %0,269\;"
+              "mfspr %L0,268\;"
+              "mfspr %1,269\;"
+              "cmpw %2,%0,%1\;"
+              "bne- %2,$-16";
+      }
+    else
+      {
+        return "mftbu %0\;"
+              "mftb %L0\;"
+              "mftbu %1\;"
+              "cmpw %2,%0,%1\;"
+              "bne- %2,$-16";
+      }
+  else
+    if (TARGET_MFCRF)
+      {
+        return "mfspr %L0,269\;"
+              "mfspr %0,268\;"
+              "mfspr %1,269\;"
+              "cmpw %2,%L0,%1\;"
+              "bne- %2,$-16";
+      }
+    else
+      {
+        return "mftbu %L0\;"
+              "mftb %0\;"
+              "mftbu %1\;"
+              "cmpw %2,%L0,%1\;"
+              "bne- %2,$-16";
+      }
+})
+
+(define_insn "rs6000_mftb_<mode>"
+  [(set (match_operand:P 0 "gpc_reg_operand" "=r")
+        (unspec_volatile:P [(const_int 0)] UNSPECV_MFTB))]
+  ""
+{
+  if (TARGET_MFCRF)
+    return "mfspr %0,268";
+  else
+    return "mftb %0";
+})
+
 \f
 
 (include "sync.md")
index e850266..5a75d45 100644 (file)
@@ -8647,6 +8647,7 @@ instructions, but allow the compiler to schedule those calls.
 * MIPS Loongson Built-in Functions::
 * Other MIPS Built-in Functions::
 * picoChip Built-in Functions::
+* PowerPC Built-in Functions::
 * PowerPC AltiVec/VSX Built-in Functions::
 * RX Built-in Functions::
 * SPARC VIS Built-in Functions::
@@ -11596,6 +11597,38 @@ GCC defines the preprocessor macro @code{___GCC_HAVE_BUILTIN_MIPS_CACHE}
 when this function is available.
 @end table
 
+@node PowerPC Built-in Functions
+@subsection PowerPC Built-in Functions
+
+These built-in functions are available for the PowerPC family of
+processors:
+@smallexample
+float __builtin_recipdivf (float, float);
+float __builtin_rsqrtf (float);
+double __builtin_recipdiv (double, double);
+double __builtin_rsqrt (double);
+long __builtin_bpermd (long, long);
+uint64_t __builtin_ppc_get_timebase ();
+unsigned long __builtin_ppc_mftb ();
+@end smallexample
+
+The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
+@code{__builtin_rsqrtf} functions generate multiple instructions to
+implement the reciprocal sqrt functionality using reciprocal sqrt
+estimate instructions.
+
+The @code{__builtin_recipdiv}, and @code{__builtin_recipdivf}
+functions generate multiple instructions to implement division using
+the reciprocal estimate instructions.
+
+The @code{__builtin_ppc_get_timebase} and @code{__builtin_ppc_mftb}
+functions generate instructions to read the Time Base Register.  The
+@code{__builtin_ppc_get_timebase} function may generate multiple
+instructions and always returns the 64 bits of the Time Base Register.
+The @code{__builtin_ppc_mftb} function always generates one instruction and
+returns the Time Base Register value as an unsigned long, throwing away
+the most significant word on 32-bit environments.
+
 @node PowerPC AltiVec/VSX Built-in Functions
 @subsection PowerPC AltiVec Built-in Functions
 
@@ -13653,24 +13686,6 @@ if the VSX instruction set is available.  The @samp{vec_vsx_ld} and
 @samp{vec_vsx_st} builtins will always generate the VSX @samp{LXVD2X},
 @samp{LXVW4X}, @samp{STXVD2X}, and @samp{STXVW4X} instructions.
 
-GCC provides a few other builtins on Powerpc to access certain instructions:
-@smallexample
-float __builtin_recipdivf (float, float);
-float __builtin_rsqrtf (float);
-double __builtin_recipdiv (double, double);
-double __builtin_rsqrt (double);
-long __builtin_bpermd (long, long);
-@end smallexample
-
-The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
-@code{__builtin_rsqrtf} functions generate multiple instructions to
-implement the reciprocal sqrt functionality using reciprocal sqrt
-estimate instructions.
-
-The @code{__builtin_recipdiv}, and @code{__builtin_recipdivf}
-functions generate multiple instructions to implement division using
-the reciprocal estimate instructions.
-
 @node RX Built-in Functions
 @subsection RX Built-in Functions
 GCC supports some of the RX instructions which cannot be expressed in