OSDN Git Service

2006-08-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / builtins.c
index 603106a..47c61cd 100644 (file)
@@ -509,12 +509,16 @@ expand_builtin_return_addr (enum built_in_function fndecl_code, int count)
 #else
   rtx tem;
 
-  /* For a zero count, we don't care what frame address we return, so frame
-     pointer elimination is OK, and using the soft frame pointer is OK.
-     For a nonzero count, we require a stable offset from the current frame
-     pointer to the previous one, so we must use the hard frame pointer, and
+  /* For a zero count with __builtin_return_address, we don't care what
+     frame address we return, because target-specific definitions will
+     override us.  Therefore frame pointer elimination is OK, and using
+     the soft frame pointer is OK.
+
+     For a non-zero count, or a zero count with __builtin_frame_address,
+     we require a stable offset from the current frame pointer to the
+     previous one, so we must use the hard frame pointer, and
      we must disable frame pointer elimination.  */
-  if (count == 0)
+  if (count == 0 && fndecl_code == BUILT_IN_RETURN_ADDRESS)
     tem = frame_pointer_rtx;
   else
     {
@@ -6768,6 +6772,42 @@ fold_fixed_mathfn (tree fndecl, tree arglist)
          return build_function_call_expr (decl, arglist);
        }
     }
+
+  /* Canonicalize llround (x) to lround (x) on LP64 targets where
+     sizeof (long long) == sizeof (long).  */
+  if (TYPE_PRECISION (long_long_integer_type_node)
+      == TYPE_PRECISION (long_integer_type_node))
+    {
+      tree newfn = NULL_TREE;
+      switch (fcode)
+       {
+       CASE_FLT_FN (BUILT_IN_LLCEIL):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LCEIL);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLFLOOR):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LFLOOR);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLROUND):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LROUND);
+         break;
+
+       CASE_FLT_FN (BUILT_IN_LLRINT):
+         newfn = mathfn_built_in (TREE_TYPE (arg), BUILT_IN_LRINT);
+         break;
+
+       default:
+         break;
+       }
+
+      if (newfn)
+       {
+         tree newcall = build_function_call_expr (newfn, arglist);
+         return fold_convert (TREE_TYPE (TREE_TYPE (fndecl)), newcall);
+       }
+    }
+
   return 0;
 }