rs6000.c (rs6000_default_long_calls, [...]): New.
authorZack Weinberg <zack@gcc.gnu.org>
Sat, 11 May 2002 16:25:05 +0000 (16:25 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Sat, 11 May 2002 16:25:05 +0000 (16:25 +0000)
* 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

gcc/ChangeLog
gcc/config.gcc
gcc/config/rs6000/rs6000-c.c [new file with mode: 0644]
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/t-rs6000-c-rule [new file with mode: 0644]
gcc/doc/extend.texi
gcc/doc/invoke.texi

index 019c96dd9014bea9b4de8bd0b94c6dfa54e56adf..093d96947e7a073228476de2aac3308395b00253 100644 (file)
@@ -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>
 
index 15038c54769438c65b978a64270870efe67b4e35..e6c268c1aec3bad545f752c6d7780b41c911553f 100644 (file)
@@ -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 (file)
index 0000000..33ce2a1
--- /dev/null
@@ -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);
+}
index 50367e35e25ca9c96c8ab585e6ecdd1e4bcf0f7a..26bb1e6cd1353f3962c901fdec93a44a040a168d 100644 (file)
@@ -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 */
index e40340b7a0643daffe5e22bd41c27c8a55932e5c..c6b703bcc8aca17990a8b27b026d69e5685c7776 100644 (file)
@@ -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.  */
 
index f5bfbfe7addb667e0cc41423d6b2d4e6f3584d3f..91627a289b08329f44c94b2e0a63140ba3dabe45 100644 (file)
@@ -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
 \f
index 7b2cd6e7163a721aeb675491278279587f9624ea..6b66c42e088eda2122b63fbcf938c738cfdd082e 100644 (file)
 ;; 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 (file)
index 0000000..3be9d67
--- /dev/null
@@ -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)
index 2545acfa23b995c059ca968ed7a897cb60c860bb..b27bec4c3bffb36bf3b21f7d4b00a4ac230873a0 100644 (file)
@@ -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.
index d422bf2ecbf542e682c3cccee6bcc6178a6d0630..68b888fca940003245290afb5b30148fa2d8c694 100644 (file)
@@ -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.