aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zack@gcc.gnu.org>2002-05-11 16:25:05 +0000
committerZack Weinberg <zack@gcc.gnu.org>2002-05-11 16:25:05 +0000
commita5c76ee6e2c613ac4c3e309e562d51bea137c73a (patch)
tree965a5479e4bfdccd120057916613030f604465fc
parent4c476cf33a7c259d3b2ac991bbd3a6bc176b93c9 (diff)
downloadgcc-a5c76ee6e2c613ac4c3e309e562d51bea137c73a.zip
gcc-a5c76ee6e2c613ac4c3e309e562d51bea137c73a.tar.gz
gcc-a5c76ee6e2c613ac4c3e309e562d51bea137c73a.tar.bz2
rs6000.c (rs6000_default_long_calls, [...]): New.
* config/rs6000/rs6000.c (rs6000_default_long_calls, rs6000_longcall_switch, rs6000_set_default_type_attributes): New. (TARGET_SET_DEFAULT_TYPE_ATTRIBUTES): Set it. (rs6000_override_options): Handle -m(no-)longcall. (init_cumulative_args, output_mi_thunk): Check for both longcall and shortcall attributes on the function. (rs6000_attribute_table): Add "shortcall". (rs6000_handle_longcall_attribute): Update comment. (altivec_expand_unop_builtin, altivec_expand_binop_builtin, altivec_expand_ternop_builtin): Add default clauses to switches to silence warnings. * config/rs6000/rs6000.h: Declare rs6000_longcall_switch and rs6000_default_long_calls. Define REGISTER_TARGET_PRAGMAS. (TARGET_OPTIONS): Add longcall and no-longcall. * config/rs6000/rs6000.md (call_nonlocal_sysv, call_value_nonlocal_sysv): Split by alternatives. One pair accepts only SYMBOL_REFs and rejects if CALL_LONG is set in the call cookie. The other pair accepts only LR/CTR and has no restriction. * config.gcc (rs6000-*-* | powerpc*-*-* trailer stanza): Set c_target_objs, cxx_target_objs; add t-rs6000-c-rule to tmake_file. * config/rs6000/rs6000-c.c: New file. * config/rs6000/t-rs6000-c-rule: New file. * config/rs6000/rs6000-protos.c: Add multiple-include guard. Prototype rs6000_pragma_longcall. * doc/extend.texi: Document shortcall attribute. * doc/invoke.texi: Document -mlongcall, -mno-longcall. From-SVN: r53382
-rw-r--r--gcc/ChangeLog95
-rw-r--r--gcc/config.gcc3
-rw-r--r--gcc/config/rs6000/rs6000-c.c71
-rw-r--r--gcc/config/rs6000/rs6000-protos.h9
-rw-r--r--gcc/config/rs6000/rs6000.c68
-rw-r--r--gcc/config/rs6000/rs6000.h10
-rw-r--r--gcc/config/rs6000/rs6000.md109
-rw-r--r--gcc/config/rs6000/t-rs6000-c-rule4
-rw-r--r--gcc/doc/extend.texi35
-rw-r--r--gcc/doc/invoke.texi18
10 files changed, 336 insertions, 86 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 019c96d..093d969 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,38 @@
+2002-05-11 Zack Weinberg <zack@codesourcery.com>
+
+ * config/rs6000/rs6000.c (rs6000_default_long_calls,
+ rs6000_longcall_switch, rs6000_set_default_type_attributes): New.
+ (TARGET_SET_DEFAULT_TYPE_ATTRIBUTES): Set it.
+ (rs6000_override_options): Handle -m(no-)longcall.
+ (init_cumulative_args, output_mi_thunk): Check for both
+ longcall and shortcall attributes on the function.
+ (rs6000_attribute_table): Add "shortcall".
+ (rs6000_handle_longcall_attribute): Update comment.
+ (altivec_expand_unop_builtin, altivec_expand_binop_builtin,
+ altivec_expand_ternop_builtin): Add default clauses to switches
+ to silence warnings.
+
+ * config/rs6000/rs6000.h: Declare rs6000_longcall_switch and
+ rs6000_default_long_calls. Define REGISTER_TARGET_PRAGMAS.
+ (TARGET_OPTIONS): Add longcall and no-longcall.
+
+ * config/rs6000/rs6000.md (call_nonlocal_sysv,
+ call_value_nonlocal_sysv): Split by alternatives. One pair
+ accepts only SYMBOL_REFs and rejects if CALL_LONG is set in
+ the call cookie. The other pair accepts only LR/CTR and has
+ no restriction.
+
+ * config.gcc (rs6000-*-* | powerpc*-*-* trailer stanza):
+ Set c_target_objs, cxx_target_objs; add t-rs6000-c-rule to
+ tmake_file.
+ * config/rs6000/rs6000-c.c: New file.
+ * config/rs6000/t-rs6000-c-rule: New file.
+ * config/rs6000/rs6000-protos.c: Add multiple-include guard.
+ Prototype rs6000_pragma_longcall.
+
+ * doc/extend.texi: Document shortcall attribute.
+ * doc/invoke.texi: Document -mlongcall, -mno-longcall.
+
2002-05-12 Marek Michalkiewicz <marekm@amelek.gda.pl>
* config/avr/avr.c (avr_mcu_types): Update supported devices.
@@ -205,38 +240,38 @@ Thu May 9 14:52:45 CEST 2002 Jan Hubicka <jh@suse.cz>
* final.c (end_final): Use C trees to output data structures for profiling.
* Makefile.in (LIBGCC_DEPS): Added missing dependency on gcov-io.h
- (profile.o): New dependency profile.h
- (final.o): New dependency profile.h
- * profile.h: New file. New global structure profile_info.
- * final.h (count_edges_instrumented_now): Declare.
- (current_function_cfg_checksum): Declare.
- (function_list): New structure.
- (functions_head, functions_tail): New static variables.
- (end_final): Emits more data, removed some -ax stuff.
- (final): Stores function names and chcksums.
- * gcov-io.h (__write_gcov_string): New function.
- (__read_gcov_string): New function.
- * gcov.c (read_profile): New function.
- (create_program_flow_graph): Uses read_profile instead of reading
+ (profile.o): New dependency profile.h
+ (final.o): New dependency profile.h
+ * profile.h: New file. New global structure profile_info.
+ * final.h (count_edges_instrumented_now): Declare.
+ (current_function_cfg_checksum): Declare.
+ (function_list): New structure.
+ (functions_head, functions_tail): New static variables.
+ (end_final): Emits more data, removed some -ax stuff.
+ (final): Stores function names and chcksums.
+ * gcov-io.h (__write_gcov_string): New function.
+ (__read_gcov_string): New function.
+ * gcov.c (read_profile): New function.
+ (create_program_flow_graph): Uses read_profile instead of reading
da_file.
- (read_files): Removed da_file checking, it's done by read_profile now.
- * libgcc2.c (bb_function_info): New structure.
- (bb): New field in structure, removed some -ax stuff.
- (__bb_exit_func): Changed structure of da_file.
- * profile.c (count_edges_instrumented_now): New global variable.
- (current_function_cfg_checksum): New global variable.
- (max_counter_in_program): New global variable.
- (get_exec_counts): New function.
- (compute_checksum): New function.
- (instrument_edges): Sets count_edges_instrumented_now.
- (compute_branch_probabilities): Uses get_exec_counts instead of
+ (read_files): Removed da_file checking, it's done by read_profile now.
+ * libgcc2.c (bb_function_info): New structure.
+ (bb): New field in structure, removed some -ax stuff.
+ (__bb_exit_func): Changed structure of da_file.
+ * profile.c (count_edges_instrumented_now): New global variable.
+ (current_function_cfg_checksum): New global variable.
+ (max_counter_in_program): New global variable.
+ (get_exec_counts): New function.
+ (compute_checksum): New function.
+ (instrument_edges): Sets count_edges_instrumented_now.
+ (compute_branch_probabilities): Uses get_exec_counts instead of
reading da_file.
- (branch_prob): Calls compute_checksum and writes extra data to bbg_file.
- (init_branch_prob): Removed da_file checking, done in get_exec_counts
+ (branch_prob): Calls compute_checksum and writes extra data to bbg_file.
+ (init_branch_prob): Removed da_file checking, done in get_exec_counts
now.
- (end_branch_prob): Removed da_file checking, done in get_exec_counts
+ (end_branch_prob): Removed da_file checking, done in get_exec_counts
now.
- * gcov.texi: Updated information about gcov file format.
+ * gcov.texi: Updated information about gcov file format.
2002-05-09 Kazu Hirata <kazu@cs.umass.edu>
@@ -347,7 +382,7 @@ doc:
* config/arm/t-arm-elf (MULTILIB): Do not allow big-endian/
little-endian multilibs to override arm/thumb multilibs.
- Do not build hardware floating point multilibs, nor apcs-26
+ Do not build hardware floating point multilibs, nor apcs-26
multilibs for the Thumb.
2002-05-08 Mark Mitchell <mark@codesourcery.com>
@@ -496,7 +531,7 @@ Tue May 7 10:06:22 2002 Jeffrey A Law (law@redhat.com)
2002-05-07 Aldy Hernandez <aldyh@redhat.com>
- * config/rs6000/rs6000.c (bdesc_2arg): Fix vmax typos.
+ * config/rs6000/rs6000.c (bdesc_2arg): Fix vmax typos.
2002-05-06 David S. Miller <davem@redhat.com>
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 15038c5..e6c268c 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -3650,6 +3650,9 @@ powerpc*-*-* | rs6000-*-*)
fi
;;
esac
+ c_target_objs="rs6000-c.o"
+ cxx_target_objs="rs6000-c.o"
+ tmake_file="${tmake_file} rs6000/t-rs6000-c-rule"
;;
sparc*-*-*)
case ".$with_cpu" in
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
new file mode 100644
index 0000000..33ce2a1
--- /dev/null
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -0,0 +1,71 @@
+/* Subroutines for the C front end on the POWER and PowerPC architectures.
+ Copyright (C) 2002
+ Free Software Foundation, Inc.
+
+ Contributed by Zack Weinberg <zack@codesourcery.com>
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+#include "config.h"
+#include "system.h"
+#include "cpplib.h"
+#include "tree.h"
+#include "c-lex.h"
+#include "errors.h"
+#include "tm_p.h"
+
+/* Handle the machine specific pragma longcall. Its syntax is
+
+ # pragma longcall ( TOGGLE )
+
+ where TOGGLE is either 0 or 1.
+
+ rs6000_default_long_calls is set to the value of TOGGLE, changing
+ whether or not new function declarations receive a longcall
+ attribute by default. */
+
+#define SYNTAX_ERROR(msgid) do { \
+ warning (msgid); \
+ warning ("ignoring malformed #pragma longcall"); \
+ return; \
+} while (0)
+
+void
+rs6000_pragma_longcall (pfile)
+ cpp_reader *pfile ATTRIBUTE_UNUSED;
+{
+ tree x, n;
+
+ /* If we get here, generic code has already scanned the directive
+ leader and the word "longcall". */
+
+ if (c_lex (&x) != CPP_OPEN_PAREN)
+ SYNTAX_ERROR ("missing open paren");
+ if (c_lex (&n) != CPP_NUMBER)
+ SYNTAX_ERROR ("missing number");
+ if (c_lex (&x) != CPP_CLOSE_PAREN)
+ SYNTAX_ERROR ("missing close paren");
+
+ if (n != integer_zero_node && n != integer_one_node)
+ SYNTAX_ERROR ("number must be 0 or 1");
+
+ if (c_lex (&x) != CPP_EOF)
+ warning ("junk at end of #pragma longcall");
+
+ rs6000_default_long_calls = (n == integer_one_node);
+}
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 50367e3..26bb1e6 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -19,6 +19,9 @@ along with GNU CC; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef GCC_RS6000_PROTOS_H
+#define GCC_RS6000_PROTOS_H
+
/* Declare functions in rs6000.c */
#ifdef RTX_CODE
@@ -186,3 +189,9 @@ extern void rs6000_emit_epilogue PARAMS ((int));
extern void debug_stack_info PARAMS ((rs6000_stack_t *));
extern void machopic_output_stub PARAMS ((FILE *, const char *, const char *));
+
+#ifdef GCC_CPPLIB_H
+extern void rs6000_pragma_longcall PARAMS ((cpp_reader *));
+#endif
+
+#endif /* rs6000-protos.h */
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e40340b..c6b703b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -124,6 +124,13 @@ char toc_label_name[10];
/* Alias set for saves and restores from the rs6000 stack. */
static int rs6000_sr_alias_set;
+/* Call distance, overridden by -mlongcall and #pragma longcall(1).
+ The only place that looks at this is rs6000_set_default_type_attributes;
+ everywhere else should rely on the presence or absence of a longcall
+ attribute on the function declaration. */
+int rs6000_default_long_calls;
+const char *rs6000_longcall_switch;
+
static void rs6000_add_gc_roots PARAMS ((void));
static int num_insns_constant_wide PARAMS ((HOST_WIDE_INT));
static rtx expand_block_move_mem PARAMS ((enum machine_mode, rtx, rtx));
@@ -146,6 +153,7 @@ static bool rs6000_assemble_integer PARAMS ((rtx, unsigned int, int));
static int rs6000_ra_ever_killed PARAMS ((void));
static tree rs6000_handle_longcall_attribute PARAMS ((tree *, tree, tree, int, bool *));
const struct attribute_spec rs6000_attribute_table[];
+static void rs6000_set_default_type_attributes PARAMS ((tree));
static void rs6000_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
static void rs6000_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
static rtx rs6000_emit_set_long_const PARAMS ((rtx,
@@ -235,6 +243,8 @@ static const char alt_reg_names[][8] =
/* Initialize the GCC target structure. */
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE rs6000_attribute_table
+#undef TARGET_SET_DEFAULT_TYPE_ATTRIBUTES
+#define TARGET_SET_DEFAULT_TYPE_ATTRIBUTES rs6000_set_default_type_attributes
#undef TARGET_ASM_ALIGNED_DI_OP
#define TARGET_ASM_ALIGNED_DI_OP DOUBLE_INT_ASM_OP
@@ -546,6 +556,22 @@ rs6000_override_options (default_cpu)
/* Handle -mvrsave= option. */
rs6000_parse_vrsave_option ();
+ /* Handle -m(no-)longcall option. This is a bit of a cheap hack,
+ using TARGET_OPTIONS to handle a toggle switch, but we're out of
+ bits in target_flags so TARGET_SWITCHES cannot be used.
+ Assumption here is that rs6000_longcall_switch points into the
+ text of the complete option, rather than being a copy, so we can
+ scan back for the presence or absence of the no- modifier. */
+ if (rs6000_longcall_switch)
+ {
+ const char *base = rs6000_longcall_switch;
+ while (base[-1] != 'm') base--;
+
+ if (*rs6000_longcall_switch != '\0')
+ error ("invalid option `%s'", base);
+ rs6000_default_long_calls = (base[0] != 'n');
+ }
+
#ifdef TARGET_REGNAMES
/* If the user desires alternate register names, copy in the
alternate names now. */
@@ -2541,8 +2567,10 @@ init_cumulative_args (cum, fntype, libname, incoming)
cum->orig_nargs = cum->nargs_prototype;
- /* Check for longcall's */
- if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
+ /* Check for a longcall attribute. */
+ if (fntype
+ && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype))
+ && !lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_LONG;
if (TARGET_DEBUG_ARG)
@@ -3565,6 +3593,8 @@ altivec_expand_unop_builtin (icode, arglist, target)
return NULL_RTX;
}
break;
+ default:
+ break;
}
if (target == 0
@@ -3654,6 +3684,8 @@ altivec_expand_binop_builtin (icode, arglist, target)
return NULL_RTX;
}
break;
+ default:
+ break;
}
if (target == 0
@@ -3828,6 +3860,8 @@ altivec_expand_ternop_builtin (icode, arglist, target)
return NULL_RTX;
}
break;
+ default:
+ break;
}
if (target == 0
@@ -9871,8 +9905,11 @@ output_mi_thunk (file, thunk_fndecl, delta, function)
fname = XSTR (XEXP (DECL_RTL (function), 0), 0);
if (current_file_function_operand (XEXP (DECL_RTL (function), 0), VOIDmode)
- && ! lookup_attribute ("longcall",
- TYPE_ATTRIBUTES (TREE_TYPE (function))))
+ && (! lookup_attribute ("longcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (function)))
+ || lookup_attribute ("shortcall",
+ TYPE_ATTRIBUTES (TREE_TYPE (function)))))
+
{
fprintf (file, "\tb %s", prefix);
assemble_name (file, fname);
@@ -10852,12 +10889,13 @@ rs6000_initialize_trampoline (addr, fnaddr, cxt)
const struct attribute_spec rs6000_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
- { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
- { NULL, 0, 0, false, false, false, NULL }
+ { "longcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
+ { "shortcall", 0, 0, false, true, true, rs6000_handle_longcall_attribute },
+ { NULL, 0, 0, false, false, false, NULL }
};
-/* Handle a "longcall" attribute; arguments as in struct
- attribute_spec.handler. */
+/* Handle a "longcall" or "shortcall" attribute; arguments as in
+ struct attribute_spec.handler. */
static tree
rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
@@ -10879,6 +10917,20 @@ rs6000_handle_longcall_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
+/* Set longcall attributes on all functions declared when
+ rs6000_default_long_calls is true. */
+static void
+rs6000_set_default_type_attributes (type)
+ tree type;
+{
+ if (rs6000_default_long_calls
+ && (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE))
+ TYPE_ATTRIBUTES (type) = tree_cons (get_identifier ("longcall"),
+ NULL_TREE,
+ TYPE_ATTRIBUTES (type));
+}
+
/* Return a reference suitable for calling a function with the
longcall attribute. */
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index f5bfbfe..91627a2 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -432,6 +432,9 @@ extern enum processor_type rs6000_cpu;
N_("Specify size of long double (64 or 128 bits)") }, \
{"vrsave=", &rs6000_altivec_vrsave_string, \
N_("Specify yes/no if VRSAVE instructions should be generated for AltiVec") }, \
+ {"longcall", &rs6000_longcall_switch, \
+ N_("Avoid all range limits on call instructions") }, \
+ {"no-longcall", &rs6000_longcall_switch, "" }, \
SUBTARGET_OPTIONS \
}
@@ -462,6 +465,8 @@ extern int rs6000_long_double_type_size;
extern int rs6000_altivec_abi;
extern const char *rs6000_altivec_vrsave_string;
extern int rs6000_altivec_vrsave;
+extern const char *rs6000_longcall_switch;
+extern int rs6000_default_long_calls;
#define TARGET_LONG_DOUBLE_128 (rs6000_long_double_type_size == 128)
#define TARGET_ALTIVEC_ABI rs6000_altivec_abi
@@ -483,6 +488,11 @@ extern int rs6000_altivec_vrsave;
/* Define this to change the optimizations performed by default. */
#define OPTIMIZATION_OPTIONS(LEVEL,SIZE) optimization_options(LEVEL,SIZE)
+/* Target pragma. */
+#define REGISTER_TARGET_PRAGMAS(PFILE) do { \
+ cpp_register_pragma (PFILE, 0, "longcall", rs6000_pragma_longcall); \
+} while (0)
+
/* Show we can debug even without a frame pointer. */
#define CAN_DEBUG_WITHOUT_FP
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 7b2cd6e..6b66c42 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -10036,68 +10036,89 @@
;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
;; which indicates how to set cr1
-(define_insn "*call_nonlocal_sysv"
- [(call (mem:SI (match_operand:SI 0 "call_operand" "cl,cl,s,s"))
- (match_operand 1 "" "g,g,g,g"))
- (use (match_operand:SI 2 "immediate_operand" "O,n,O,n"))
- (clobber (match_scratch:SI 3 "=l,l,l,l"))]
+(define_insn "*call_indirect_nonlocal_sysv"
+ [(call (mem:SI (match_operand:SI 0 "register_operand" "cl,cl"))
+ (match_operand 1 "" "g,g"))
+ (use (match_operand:SI 2 "immediate_operand" "O,n"))
+ (clobber (match_scratch:SI 3 "=l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
- "*
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
- output_asm_insn (\"crxor 6,6,6\", operands);
+ output_asm_insn ("crxor 6,6,6", operands);
else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
- output_asm_insn (\"creqv 6,6,6\", operands);
+ output_asm_insn ("creqv 6,6,6", operands);
- switch (which_alternative)
- {
- default:
- abort ();
- case 0:
- case 1:
- return \"b%T0l\";
- case 2:
- case 3:
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@plt\" : \"bl %z0\";
- }
-}"
- [(set_attr "type" "jmpreg,jmpreg,branch,branch")
- (set_attr "length" "4,8,4,8")])
+ return "b%T0l";
+}
+ [(set_attr "type" "jmpreg,jmpreg")
+ (set_attr "length" "4,8")])
-(define_insn "*call_value_nonlocal_sysv"
+(define_insn "*call_nonlocal_sysv"
+ [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s,s"))
+ (match_operand 1 "" "g,g"))
+ (use (match_operand:SI 2 "immediate_operand" "O,n"))
+ (clobber (match_scratch:SI 3 "=l,l"))]
+ "(DEFAULT_ABI == ABI_AIX_NODESC
+ || DEFAULT_ABI == ABI_V4
+ || DEFAULT_ABI == ABI_DARWIN)
+ && (INTVAL (operands[2]) & CALL_LONG) == 0"
+{
+ if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
+ output_asm_insn ("crxor 6,6,6", operands);
+
+ else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
+ output_asm_insn ("creqv 6,6,6", operands);
+
+ return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@plt" : "bl %z0";
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_value_indirect_nonlocal_sysv"
[(set (match_operand 0 "" "")
- (call (mem:SI (match_operand:SI 1 "call_operand" "cl,cl,s,s"))
- (match_operand 2 "" "g,g,g,g")))
- (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
- (clobber (match_scratch:SI 4 "=l,l,l,l"))]
+ (call (mem:SI (match_operand:SI 1 "register_operand" "cl,cl"))
+ (match_operand 2 "" "g,g")))
+ (use (match_operand:SI 3 "immediate_operand" "O,n"))
+ (clobber (match_scratch:SI 4 "=l,l"))]
"DEFAULT_ABI == ABI_AIX_NODESC
|| DEFAULT_ABI == ABI_V4
|| DEFAULT_ABI == ABI_DARWIN"
- "*
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
- output_asm_insn (\"crxor 6,6,6\", operands);
+ output_asm_insn ("crxor 6,6,6", operands);
else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
- output_asm_insn (\"creqv 6,6,6\", operands);
+ output_asm_insn ("creqv 6,6,6", operands);
- switch (which_alternative)
- {
- default:
- abort ();
- case 0:
- case 1:
- return \"b%T1l\";
- case 2:
- case 3:
- return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@plt\" : \"bl %z1\";
- }
-}"
- [(set_attr "type" "jmpreg,jmpreg,branch,branch")
- (set_attr "length" "4,8,4,8")])
+ return "b%T1l";
+}
+ [(set_attr "type" "jmpreg,jmpreg")
+ (set_attr "length" "4,8")])
+
+(define_insn "*call_value_nonlocal_sysv"
+ [(set (match_operand 0 "" "")
+ (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s,s"))
+ (match_operand 2 "" "g,g")))
+ (use (match_operand:SI 3 "immediate_operand" "O,n"))
+ (clobber (match_scratch:SI 4 "=l,l"))]
+ "(DEFAULT_ABI == ABI_AIX_NODESC
+ || DEFAULT_ABI == ABI_V4
+ || DEFAULT_ABI == ABI_DARWIN)
+ && (INTVAL (operands[3]) & CALL_LONG) == 0"
+{
+ if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
+ output_asm_insn ("crxor 6,6,6", operands);
+
+ else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
+ output_asm_insn ("creqv 6,6,6", operands);
+
+ return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@plt" : "bl %z1";
+}
+ [(set_attr "type" "branch,branch")
+ (set_attr "length" "4,8")])
;; Call subroutine returning any type.
(define_expand "untyped_call"
diff --git a/gcc/config/rs6000/t-rs6000-c-rule b/gcc/config/rs6000/t-rs6000-c-rule
new file mode 100644
index 0000000..3be9d67
--- /dev/null
+++ b/gcc/config/rs6000/t-rs6000-c-rule
@@ -0,0 +1,4 @@
+rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
+ $(srcdir)/config/rs6000/rs6000-protos.h \
+ $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(CPPLIB_H) $(TM_P_H) c-lex.h errors.h
+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 2545acf..b27bec4 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -2273,12 +2273,17 @@ useful to override the effects of the @option{-mrtd} switch.
The PowerPC compiler for Windows NT currently ignores the @code{cdecl}
attribute.
-@item longcall
+@item longcall/shortcall
@cindex functions called via pointer on the RS/6000 and PowerPC
On the RS/6000 and PowerPC, the @code{longcall} attribute causes the
-compiler to always call the function via a pointer, so that functions
-which reside further than 64 megabytes (67,108,864 bytes) from the
-current location can be called.
+compiler to always call this function via a pointer, just as it would if
+the @option{-mlongcall} option had been specified. The @code{shortcall}
+attribute causes the compiler not to do this. These attributes override
+both the @option{-mlongcall} switch and the @code{#pragma longcall}
+setting.
+
+@xref{RS/6000 and PowerPC Options}, for more information on when long
+calls are and are not necessary.
@item long_call/short_call
@cindex indirect calls on ARM
@@ -5992,6 +5997,7 @@ for further explanation.
@menu
* ARM Pragmas::
+* RS/6000 and PowerPC Pragmas::
* Darwin Pragmas::
* Solaris Pragmas::
* Tru64 Pragmas::
@@ -6020,6 +6026,27 @@ Do not affect the @code{long_call} or @code{short_call} attributes of
subsequent functions.
@end table
+@node RS/6000 and PowerPC Pragmas
+@subsection RS/6000 and PowerPC Pragmas
+
+The RS/6000 and PowerPC targets define one pragma for controlling
+whether or not the @code{longcall} attribute is added to function
+declarations by default. This pragma overrides the @option{-mlongcall}
+option, but not the @code{longcall} and @code{shortcall} attributes.
+@xref{RS/6000 and PowerPC Options}, for more information about when long
+calls are and are not necessary.
+
+@table @code
+@item longcall (1)
+@cindex pragma, longcall
+Apply the @code{longcall} attribute to all subsequent function
+declarations.
+
+@item longcall (0)
+Do not apply the @code{longcall} attribute to subsequent function
+declarations.
+@end table
+
@c Describe c4x pragmas here.
@c Describe h8300 pragmas here.
@c Describe i370 pragmas here.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d422bf2..68b888f 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -6817,6 +6817,24 @@ All modules should be compiled with the same @option{-G @var{num}} value.
On System V.4 and embedded PowerPC systems do (do not) emit register
names in the assembly language output using symbolic forms.
+@item -mlongcall
+@itemx -mno-longcall
+@opindex mlongcall
+@opindex mno-longcall
+Default to making all function calls via pointers, so that functions
+which reside further than 64 megabytes (67,108,864 bytes) from the
+current location can be called. This setting can be overridden by the
+@code{shortcall} function attribute, or by @code{#pragma longcall(0)}.
+
+Some linkers are capable of detecting out-of-range calls and generating
+glue code on the fly. On these systems, long calls are unnecessary and
+generate slower code. As of this writing, the AIX linker can do this,
+as can the GNU linker for PowerPC/64. It is planned to add this feature
+to the GNU linker for 32-bit PowerPC systems as well.
+
+In the future, we may cause GCC to ignore all longcall specifications
+when the linker is known to generate glue.
+
@item -pthread
@opindex pthread
Adds support for multithreading with the @dfn{pthreads} library.