+2011-04-22 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_function_arg): Remove CALL_LIBCALL
+ when returning call_cookie.
+ (rs6000_function_ok_for_sibcall): Allow sibcalls via function
+ pointers, to functions with no more vector args than the current
+ function, and some non-local calls for ABI_V4.
+ * config/rs6000/rs6000.md (sibcall_nonlocal_aix32,
+ sibcall_nonlocal_aix64): Combine to ..
+ (sibcall_nonlocal_aix<mode>): ..this. Handle function pointer calls.
+ (sibcall_value_nonlocal_aix32, sibcall_value_nonlocal_aix64): Combine..
+ (sibcall_value_nonlocal_aix<mode>): ..likewise.
+ (*sibcall_nonlocal_sysv<mode>): Handle function pointer calls.
+ (sibcall_value_nonlocal_sysv<mode>): Likewise. Correct call cookie
+ operand.
+ * config/rs6000/darwin.md (sibcall_nonlocal_darwin64,
+ sibcall_value_nonlocal_darwin64, sibcall_symbolic_64,
+ sibcall_value_symbolic_64): Delete.
+
2011-04-21 Xinliang David Li <davidxl@google.com>
* cgraph.h: Remove pid.
/* Machine description patterns for PowerPC running Darwin (Mac OS X).
- Copyright (C) 2004, 2005, 2007, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
This file is part of GCC.
}
[(set_attr "type" "branch,branch")
(set_attr "length" "4,8")])
-
-(define_insn "*sibcall_nonlocal_darwin64"
- [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
- (match_operand 1 "" ""))
- (use (match_operand 2 "immediate_operand" "O,n"))
- (use (reg:SI 65))
- (return)]
- "(DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
-{
- return "b %z0";
-}
- [(set_attr "type" "branch,branch")
- (set_attr "length" "4,8")])
-
-(define_insn "*sibcall_value_nonlocal_darwin64"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
- (match_operand 2 "" "")))
- (use (match_operand:SI 3 "immediate_operand" "O,n"))
- (use (reg:SI 65))
- (return)]
- "(DEFAULT_ABI == ABI_DARWIN)
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
- "*
-{
- return \"b %z1\";
-}"
- [(set_attr "type" "branch,branch")
- (set_attr "length" "4,8")])
-
-
-(define_insn "*sibcall_symbolic_64"
- [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64
- (match_operand 1 "" ""))
- (use (match_operand 2 "" ""))
- (use (reg:SI 65))
- (return)]
- "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
- "*
-{
- switch (which_alternative)
- {
- case 0: return \"b %z0\";
- case 1: return \"b%T0\";
- default: gcc_unreachable ();
- }
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-(define_insn "*sibcall_value_symbolic_64"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:DI 1 "call_operand" "s,c"))
- (match_operand 2 "" "")))
- (use (match_operand:SI 3 "" ""))
- (use (reg:SI 65))
- (return)]
- "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
- "*
-{
- switch (which_alternative)
- {
- case 0: return \"b %z1\";
- case 1: return \"b%T1\";
- default: gcc_unreachable ();
- }
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
return get_hard_reg_initial_val (Pmode, LR_REGNO);
}
-/* Say whether a function is a candidate for sibcall handling or not.
- We do not allow indirect calls to be optimized into sibling calls.
- Also, we can't do it if there are any vector parameters; there's
- nowhere to put the VRsave code so it works; note that functions with
- vector parameters are required to have a prototype, so the argument
- type info must be available here. (The tail recursion case can work
- with vector parameters, but there's no way to distinguish here.) */
+/* Say whether a function is a candidate for sibcall handling or not. */
+
static bool
-rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+rs6000_function_ok_for_sibcall (tree decl, tree exp)
{
- tree type;
+ tree fntype;
+
if (decl)
+ fntype = TREE_TYPE (decl);
+ else
+ fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
+
+ /* We can't do it if the called function has more vector parameters
+ than the current function; there's nowhere to put the VRsave code. */
+ if (TARGET_ALTIVEC_ABI
+ && TARGET_ALTIVEC_VRSAVE
+ && !(decl && decl == current_function_decl))
{
- if (TARGET_ALTIVEC_VRSAVE)
- {
- for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
- type; type = TREE_CHAIN (type))
- {
- if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
- return false;
- }
- }
- if (DEFAULT_ABI == ABI_DARWIN
- || ((*targetm.binds_local_p) (decl)
- && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
- {
- tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+ function_args_iterator args_iter;
+ tree type;
+ int nvreg = 0;
+
+ /* Functions with vector parameters are required to have a
+ prototype, so the argument type info must be available
+ here. */
+ FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
+ if (TREE_CODE (type) == VECTOR_TYPE
+ && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type))
+ || VSX_VECTOR_MODE (TYPE_MODE (type))))
+ nvreg++;
+
+ FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
+ if (TREE_CODE (type) == VECTOR_TYPE
+ && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type))
+ || VSX_VECTOR_MODE (TYPE_MODE (type))))
+ nvreg--;
+
+ if (nvreg > 0)
+ return false;
+ }
- if (!lookup_attribute ("longcall", attr_list)
- || lookup_attribute ("shortcall", attr_list))
- return true;
- }
+ /* Under the AIX ABI we can't allow calls to non-local functions,
+ because the callee may have a different TOC pointer to the
+ caller and there's no way to ensure we restore the TOC when we
+ return. With the secure-plt SYSV ABI we can't make non-local
+ calls when -fpic/PIC because the plt call stubs use r30. */
+ if (DEFAULT_ABI == ABI_DARWIN
+ || (DEFAULT_ABI == ABI_AIX
+ && decl
+ && !DECL_EXTERNAL (decl)
+ && (*targetm.binds_local_p) (decl))
+ || (DEFAULT_ABI == ABI_V4
+ && (!TARGET_SECURE_PLT
+ || !flag_pic
+ || (decl
+ && (*targetm.binds_local_p) (decl)))))
+ {
+ tree attr_list = TYPE_ATTRIBUTES (fntype);
+
+ if (!lookup_attribute ("longcall", attr_list)
+ || lookup_attribute ("shortcall", attr_list))
+ return true;
}
+
return false;
}
[(set_attr "type" "branch")
(set_attr "length" "4,8")])
-(define_insn "*sibcall_nonlocal_aix32"
- [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
- (match_operand 1 "" "g"))
- (use (match_operand:SI 2 "immediate_operand" "O"))
- (use (reg:SI LR_REGNO))
- (return)]
- "TARGET_32BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[2]) & CALL_LONG) == 0"
- "b %z0"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-(define_insn "*sibcall_nonlocal_aix64"
- [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
- (match_operand 1 "" "g"))
- (use (match_operand:SI 2 "immediate_operand" "O"))
+(define_insn "*sibcall_nonlocal_aix<mode>"
+ [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
+ (match_operand 1 "" "g,g"))
+ (use (match_operand:SI 2 "immediate_operand" "O,O"))
(use (reg:SI LR_REGNO))
(return)]
- "TARGET_64BIT
- && DEFAULT_ABI == ABI_AIX
+ "DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
- "b %z0"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-(define_insn "*sibcall_value_nonlocal_aix32"
- [(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
- (match_operand 2 "" "g")))
- (use (match_operand:SI 3 "immediate_operand" "O"))
- (use (reg:SI LR_REGNO))
- (return)]
- "TARGET_32BIT
- && DEFAULT_ABI == ABI_AIX
- && (INTVAL (operands[3]) & CALL_LONG) == 0"
- "b %z1"
+ "@
+ b %z0
+ b%T0"
[(set_attr "type" "branch")
(set_attr "length" "4")])
-(define_insn "*sibcall_value_nonlocal_aix64"
+(define_insn "*sibcall_value_nonlocal_aix<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
- (match_operand 2 "" "g")))
- (use (match_operand:SI 3 "immediate_operand" "O"))
+ (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
+ (match_operand 2 "" "g,g")))
+ (use (match_operand:SI 3 "immediate_operand" "O,O"))
(use (reg:SI LR_REGNO))
(return)]
- "TARGET_64BIT
- && DEFAULT_ABI == ABI_AIX
+ "DEFAULT_ABI == ABI_AIX
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
- "b %z1"
+ "@
+ b %z1
+ b%T1"
[(set_attr "type" "branch")
(set_attr "length" "4")])
(define_insn "*sibcall_nonlocal_sysv<mode>"
- [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
+ [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
(match_operand 1 "" ""))
- (use (match_operand 2 "immediate_operand" "O,n"))
+ (use (match_operand 2 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands);
- if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ if (which_alternative >= 2)
+ return \"b%T0\";
+ else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
gcc_assert (!TARGET_SECURE_PLT);
return \"b %z0@plt\";
else
return \"b %z0\";
}"
- [(set_attr "type" "branch,branch")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "branch")
+ (set_attr "length" "4,8,4,8")])
(define_expand "sibcall_value"
[(parallel [(set (match_operand 0 "register_operand" "")
(define_insn "*sibcall_value_nonlocal_sysv<mode>"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
+ (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
(match_operand 2 "" "")))
- (use (match_operand:SI 3 "immediate_operand" "O,n"))
+ (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
(use (reg:SI LR_REGNO))
(return)]
"(DEFAULT_ABI == ABI_DARWIN
- || DEFAULT_ABI == ABI_V4)
+ || DEFAULT_ABI == ABI_V4)
&& (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
- if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
+ if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
output_asm_insn (\"crxor 6,6,6\", operands);
- else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
+ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
output_asm_insn (\"creqv 6,6,6\", operands);
- if (DEFAULT_ABI == ABI_V4 && flag_pic)
+ if (which_alternative >= 2)
+ return \"b%T1\";
+ else if (DEFAULT_ABI == ABI_V4 && flag_pic)
{
gcc_assert (!TARGET_SECURE_PLT);
return \"b %z1@plt\";
else
return \"b %z1\";
}"
- [(set_attr "type" "branch,branch")
- (set_attr "length" "4,8")])
+ [(set_attr "type" "branch")
+ (set_attr "length" "4,8,4,8")])
(define_expand "sibcall_epilogue"
[(use (const_int 0))]
+2011-04-22 Alan Modra <amodra@gmail.com>
+
+ * gcc.target/powerpc/ppc-pow.c: Allow for tail calls.
+
2011-04-21 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/48405
/* { dg-options "-O2 -ffast-math -mcpu=power6" } */
/* { dg-final { scan-assembler-times "fsqrt" 3 } } */
/* { dg-final { scan-assembler-times "fmul" 1 } } */
-/* { dg-final { scan-assembler-times "bl pow" 1 } } */
-/* { dg-final { scan-assembler-times "bl sqrt" 1 } } */
+/* { dg-final { scan-assembler-times "bl? pow" 1 } } */
+/* { dg-final { scan-assembler-times "bl? sqrt" 1 } } */
double
do_pow_0_75_default (double a)