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.
 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
        * 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.
        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.
        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.
        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.
        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>
 
 
 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.
 
        * 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>
        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>
 
 
 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>
 
 
 2002-05-06  David S. Miller  <davem@redhat.com>
 
index 15038c54769438c65b978a64270870efe67b4e35..e6c268c1aec3bad545f752c6d7780b41c911553f 100644 (file)
@@ -3650,6 +3650,9 @@ powerpc*-*-* | rs6000-*-*)
                        fi
                        ;;
        esac
                        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
        ;;
 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.  */
 
 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
 /* 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 *));
 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;
 
 /* 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));
 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 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,
 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
 /* 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
 
 #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 -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.  */
 #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;
 
 
   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)
     cum->call_cookie = CALL_LONG;
 
   if (TARGET_DEBUG_ARG)
@@ -3565,6 +3593,8 @@ altivec_expand_unop_builtin (icode, arglist, target)
          return NULL_RTX;
        }
       break;
          return NULL_RTX;
        }
       break;
+    default:
+      break;
     }
 
   if (target == 0
     }
 
   if (target == 0
@@ -3654,6 +3684,8 @@ altivec_expand_binop_builtin (icode, arglist, target)
          return NULL_RTX;
        }
       break;
          return NULL_RTX;
        }
       break;
+    default:
+      break;
     }
 
   if (target == 0
     }
 
   if (target == 0
@@ -3828,6 +3860,8 @@ altivec_expand_ternop_builtin (icode, arglist, target)
          return NULL_RTX;
        }
       break;
          return NULL_RTX;
        }
       break;
+    default:
+      break;
     }
 
   if (target == 0
     }
 
   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)
   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);
     {
       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 } */
 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)
 
 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;
 }
 
   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.  */
 
 /* 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") }, \
     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                                                   \
 }
 
    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 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
 
 #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)
 
 /* 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
 /* 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
 
 ;; 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"
   "DEFAULT_ABI == ABI_AIX_NODESC
    || DEFAULT_ABI == ABI_V4
    || DEFAULT_ABI == ABI_DARWIN"
-  "*
 {
   if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
 {
   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)
 
   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 "" "")
   [(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"
   "DEFAULT_ABI == ABI_AIX_NODESC
    || DEFAULT_ABI == ABI_V4
    || DEFAULT_ABI == ABI_DARWIN"
-  "*
 {
   if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
 {
   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)
 
   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"
 
 ;; 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.
 
 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
 @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
 
 @item long_call/short_call
 @cindex indirect calls on ARM
@@ -5992,6 +5997,7 @@ for further explanation.
 
 @menu
 * ARM Pragmas::
 
 @menu
 * ARM Pragmas::
+* RS/6000 and PowerPC Pragmas::
 * Darwin Pragmas::
 * Solaris Pragmas::
 * Tru64 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
 
 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.
 @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.
 
 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.
 @item -pthread
 @opindex pthread
 Adds support for multithreading with the @dfn{pthreads} library.