This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Professional support for Vxworks cross-compiler
- To: gcc at gcc dot gnu dot org
- Subject: Re: Professional support for Vxworks cross-compiler
- From: Mike Stump <mrs at windriver dot com>
- Date: Fri, 7 Jul 2000 14:13:04 -0700 (PDT)
> From: dirk.huenerson@exgate.tek.com
> To: wilson@cygnus.com, law@cygnus.com
> Cc: meissner@tiktok.cygnus.com, mrs@mail.wrs.com, gcc-help@gnu.org
> Date: Fri, 7 Jul 2000 13:15:51 +0200
> 1. the cross compiler for i960 and ppc creates static objects locally and
> the global objects can not be initialised using the VxWorks DTOR CTOR tables
> created by the munch tool.
See patch below. Send Crisp new $100 bills to me.
> 2. the 68k cross compiler does not evaluate totally the -msoft-float option,
> that means illeagal op code is incorporated into the code.
I can't guess at this. I don't think I've seen it.
> 3. the ppc cross compiler can not address more then 32 MB using jump
> commands generated to handle function calls.
See second patch below. Send Crisp new $100 bills to me.
The first patch is gross and I want to fix it by dumping munch on our
side. I haven't gotten around to that yet. The second patch is I
think reasonably clean and in theory can go in. It would probably
need some cleanup and some care and feeding to get it. If someone
wants to hand hold it to get it in, I would appreciate it.
diff -N -cpr ./cp/decl2.c ./cp/decl2.c
*** ./cp/decl2.c Sat Jul 31 15:52:41 1999
--- ./cp/decl2.c Sat Jul 31 23:25:12 1999
*************** start_objects (method_type, initp)
*** 2912,2921 ****
--- 2912,2923 ----
NULL_TREE),
NULL_TREE, 0);
+ #if 0 /* WRS LOCAL - make syms public (mrs) */
#if defined(ASM_OUTPUT_CONSTRUCTOR) && defined(ASM_OUTPUT_DESTRUCTOR)
/* It can be a static function as long as collect2 does not have
to scan the object file to find its ctor/dtor routine. */
TREE_PUBLIC (current_function_decl) = 0;
+ #endif
#endif
store_parm_decls ();
-----
Wed Sep 1 09:55:54 1999 Salim Nasser <salim@wrs.com>
* config/rs6000/rs6000.c, config/rs6000/rs6000.h,
config/config/rs6000.md: added support for -mlongcall,
__attribute__ shortcall and #pragma longcall.
(rs6000_is_longcall_p): arbitrate between various
sources of info (explicit attribute, inside #pragma
longcall, -mlongcall, function defined in this file) to
determine whether or not we should generate a 32 bit
call.
(handle_other_pragma_token): handle #pragma longcall
- eventually this should be factored out into a target
independent "longcall feature".
* varasm.c, output.h, decl.c, cp/c-decl.c :
(MARK_FN_AS_DEFINED_IN_THIS_FILE) : if defined then
inform whenever we can be sure that a function has a
definition in the current translation unit.
* c-pragma.c, c-pragma.h :
(HANDLE_OTHER_PRAGMA_TOKEN) : if defined then delegate
unknown pragmas to the specified handler.
* extend.texi, invoke.texi : documented new features
diff -N -cpr ./config/rs6000/rs6000.c /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.c
*** ./config/rs6000/rs6000.c Sat Jul 31 15:44:29 1999
--- /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.c Wed Sep 1 17:46:38 1999
*************** int rs6000_debug_arg; /* debug argument
*** 112,117 ****
--- 112,120 ----
/* Flag to say the TOC is initialized */
int toc_initialized;
+ /* non-zero iff #pragma longcall is currently on */
+ int rs6000_pragma_longcall = 0;
+
/* Default register names. */
char rs6000_reg_names[][8] =
*************** init_cumulative_args (cum, fntype, libna
*** 1273,1279 ****
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_NT_DLLIMPORT;
! /* Also check for longcall's */
else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_LONG;
--- 1276,1287 ----
&& lookup_attribute ("dllimport", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_NT_DLLIMPORT;
! /* shortcall always overrides longcall */
! /* Check for __attribute__ ((shortcall)) */
! else if (fntype && lookup_attribute ("shortcall", TYPE_ATTRIBUTES (fntype)))
! cum->call_cookie = CALL_SHORT;
!
! /* Check for __attribute__ ((longcall)) */
else if (fntype && lookup_attribute ("longcall", TYPE_ATTRIBUTES (fntype)))
cum->call_cookie = CALL_LONG;
*************** init_cumulative_args (cum, fntype, libna
*** 1293,1298 ****
--- 1301,1309 ----
if (cum->call_cookie & CALL_LONG)
fprintf (stderr, " longcall,");
+ if (cum->call_cookie & CALL_SHORT)
+ fprintf (stderr, " shortcall,");
+
fprintf (stderr, " proto = %d, nargs = %d\n",
cum->prototype, cum->nargs_prototype);
}
*************** rs6000_valid_type_attribute_p (type, att
*** 5415,5420 ****
--- 5426,5435 ----
if (is_attribute_p ("longcall", identifier))
return (args == NULL_TREE);
+ /* Shortcall overrides both explicit longcalls and #pragma longcall (1) */
+ if (is_attribute_p ("shortcall", identifier))
+ return (args == NULL_TREE);
+
if (DEFAULT_ABI == ABI_NT)
{
/* Stdcall attribute says callee is responsible for popping arguments
*************** void
*** 5483,5488 ****
--- 5498,5513 ----
rs6000_set_default_type_attributes (type)
tree type ATTRIBUTE_UNUSED;
{
+ /* add __attribute__ ((longcall)) to all functions when
+ inside #pragma longcall */
+ if (rs6000_pragma_longcall && TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ tree type_attr_list, attr_name;
+ type_attr_list = TYPE_ATTRIBUTES (type);
+ attr_name = get_identifier ("longcall");
+ type_attr_list = tree_cons (attr_name, NULL_TREE, type_attr_list);
+ TYPE_ATTRIBUTES (type) = type_attr_list;
+ }
}
/* Return a dll import reference corresponding to a call's SYMBOL_REF */
*************** rs6000_dll_import_ref (call_ref)
*** 5514,5519 ****
--- 5539,5568 ----
return reg2;
}
+ /* A C expression whose value is nonzero if a 32 bit "longcall" should be
+ generated for this call. We generate a longcall if the function
+ is not declared __attribute__ ((shortcall), AND:
+ (i) the function is declared __attribute__ ((longcall))
+ (either explicitly in the source code or implicitly when
+ the declaration is within a #pragma longcall (1)), or
+ (ii) -mlongcall is enabled and we don't know whether the target function
+ is declared in this file
+ This function will typically be called by C fragments in the machine
+ description file. call_ref and call_cookie will correspond to
+ matched rtl operands.
+ */
+
+ int
+ rs6000_is_longcall_p (call_ref, call_cookie)
+ rtx call_ref;
+ int call_cookie;
+ {
+ return !(call_cookie & CALL_SHORT) &&
+ ((call_cookie & CALL_LONG) ||
+ (TARGET_LONGCALL &&
+ !current_file_function_operand (call_ref, VOIDmode)));
+ }
+
/* Return a reference suitable for calling a function with the longcall attribute. */
struct rtx_def *
rs6000_longcall_ref (call_ref)
*************** rs6000_longcall_ref (call_ref)
*** 5539,5544 ****
--- 5588,5673 ----
return force_reg (Pmode, call_ref);
}
+ /* Handle one token of a pragma directive. TOKEN is the
+ current token, and STRING is its printable form. */
+
+ void
+ handle_other_pragma_token (string, token)
+ char *string;
+ tree token;
+ {
+ static enum other_pragma_state state = ops_start, type;
+ static int longcall;
+ if (string == 0)
+ {
+ if (type == ops_longcall)
+ {
+ if (state == ops_right_longcall)
+ rs6000_pragma_longcall = longcall;
+ else
+ warning ("malformed `#pragma longcall'");
+ }
+ type = state = ops_start;
+ return;
+ }
+
+ switch (state)
+ {
+ case ops_start:
+ if (token && TREE_CODE (token) == IDENTIFIER_NODE)
+ {
+ if (strcmp (IDENTIFIER_POINTER (token), "longcall") == 0)
+ type = state = ops_longcall;
+ else
+ type = state = ops_done;
+ }
+ else
+ type = state = ops_done;
+ break;
+
+ case ops_longcall:
+ if (strcmp (string, "(") == 0)
+ state = ops_left_longcall;
+ else
+ state = ops_bad;
+ break;
+
+ case ops_left_longcall:
+ if (token && TREE_CODE (token) == INTEGER_CST
+ && TREE_INT_CST_HIGH (token) == 0)
+ switch (TREE_INT_CST_LOW (token))
+ {
+ case 0:
+ case 1:
+ longcall = TREE_INT_CST_LOW (token);
+ state = ops_switch_longcall;
+ break;
+
+ default:
+ state = ops_bad;
+ }
+ else if (! token && strcmp (string, ")") == 0)
+ {
+ longcall = 0;
+ state = ops_right_longcall;
+ }
+ else
+ state = ops_bad;
+ break;
+
+ case ops_switch_longcall:
+ if (strcmp (string, ")") == 0)
+ state = ops_right_longcall;
+ else
+ state = ops_bad;
+ break;
+
+ case ops_right_longcall:
+ state = ops_bad;
+ break;
+
+ }
+ }
/* A C statement or statements to switch to the appropriate section
for output of RTX in mode MODE. You can assume that RTX is some
diff -N -cpr ./config/rs6000/rs6000.h /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.h
*** ./config/rs6000/rs6000.h Sat Jul 31 15:44:36 1999
--- /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.h Thu Oct 7 19:12:04 1999
*************** Boston, MA 02111-1307, USA. */
*** 219,225 ****
/* Architecture type. */
! extern int target_flags;
/* Use POWER architecture instructions and MQ register. */
#define MASK_POWER 0x00000001
--- 219,225 ----
/* Architecture type. */
! extern long int target_flags;
/* Use POWER architecture instructions and MQ register. */
#define MASK_POWER 0x00000001
*************** extern int target_flags;
*** 279,284 ****
--- 279,294 ----
/* Disable fused multiply/add operations */
#define MASK_NO_FUSED_MADD 0x00020000
+ /* Use a conservative heuristic to determine whether to
+ make a direct (26) call or an indirect (32 bit) call:
+ We make a longcall unless the target function is declared
+ static, or its definition has already been seen, or
+ it is declared with the attribute "shortcall" .
+ An underlying assumption is that individual translation
+ units span less than 32MB so that it is always safe
+ to make direct calls to functions in the same module. */
+ #define MASK_LONGCALL 0x00040000
+
#define TARGET_POWER (target_flags & MASK_POWER)
#define TARGET_POWER2 (target_flags & MASK_POWER2)
#define TARGET_POWERPC (target_flags & MASK_POWERPC)
*************** extern int target_flags;
*** 297,302 ****
--- 307,313 ----
#define TARGET_STRING_SET (target_flags & MASK_STRING_SET)
#define TARGET_NO_UPDATE (target_flags & MASK_NO_UPDATE)
#define TARGET_NO_FUSED_MADD (target_flags & MASK_NO_FUSED_MADD)
+ #define TARGET_LONGCALL (target_flags & MASK_LONGCALL)
#define TARGET_32BIT (! TARGET_64BIT)
#define TARGET_HARD_FLOAT (! TARGET_SOFT_FLOAT)
*************** extern int target_flags;
*** 390,395 ****
--- 401,407 ----
{"no-update", MASK_NO_UPDATE}, \
{"fused-madd", - MASK_NO_FUSED_MADD}, \
{"no-fused-madd", MASK_NO_FUSED_MADD}, \
+ {"longcall", MASK_LONGCALL}, \
SUBTARGET_SWITCHES \
{"", TARGET_DEFAULT}}
*************** extern int rs6000_sysv_varargs_p;
*** 1407,1412 ****
--- 1419,1425 ----
#define CALL_V4_CLEAR_FP_ARGS 0x00000002 /* V.4, no FP args passed */
#define CALL_V4_SET_FP_ARGS 0x00000004 /* V.4, FP args were passed */
#define CALL_LONG 0x00000008 /* always call indirect */
+ #define CALL_SHORT 0x00000010 /* always call direct if possible */
/* Define cutoff for using external functions to save floating point */
#define FP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) == 62 || (FIRST_REG) == 63)
*************** extern int rs6000_trunc_used;
*** 2506,2511 ****
--- 2519,2548 ----
#define TARGET_MEM_FUNCTIONS
+ /* Define HANDLE_OTHER_PRAGMA_TOKEN(string, token) if you want
+ to handle pragmas other than align and weak. When handle_pragma_token
+ comes across a pragma it doesn't understand, it will delegate
+ responsibility for handling it to HANDLE_OTHER_PRAGMA_TOKEN (if defined),
+ passing it the current token (token) and its printable form (string).
+ The latter should implement its own state machine along the lines of the
+ one in handle_pragma_token. */
+
+ #define HANDLE_OTHER_PRAGMA_TOKEN(string, token) \
+ handle_other_pragma_token(string, token)
+
+ enum other_pragma_state
+ {
+ ops_start,
+ ops_done,
+ ops_bad,
+ ops_longcall,
+ ops_left_longcall,
+ ops_switch_longcall,
+ ops_right_longcall
+ };
+
+ extern int rs6000_pragma_longcall;
+
/* Define the extra sections we need. We define three: one is the read-only
data section which is used for constants. This is a csect whose name is
derived from the name of the input file. The second is for initialized
*************** extern int rs6000_trunc_used;
*** 2536,2541 ****
--- 2573,2589 ----
&& (TREE_ASM_WRITTEN (DECL) || ! TREE_PUBLIC (DECL))) \
SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1;
+ /* Optionally record the information that a function has been defined
+ in this file */
+
+ /* When we have -mlongcall we'd like to record this extra information
+ so that we can be smarter about which functions should be called
+ indirectly. */
+
+ #define MARK_FN_DEFINED_IN_THIS_FILE(DECL) \
+ if (TARGET_LONGCALL && TREE_CODE (DECL) == FUNCTION_DECL) \
+ SYMBOL_REF_FLAG (XEXP (DECL_RTL (DECL), 0)) = 1
+
/* Indicate that jump tables go in the text section. */
#define JUMP_TABLES_IN_TEXT_SECTION 1
*************** extern int function_arg_padding ();
*** 3322,3327 ****
--- 3370,3379 ----
extern void toc_section ();
extern void private_data_section ();
extern void rs6000_fatal_bad_address ();
+
+ extern int rs6000_is_longcall_p ();
+ extern struct rtx_def *rs6000_longcall_ref ();
+ extern int rs6000_pragma_longcall;
/* See nonlocal_goto_receiver for when this must be set. */
diff -N -cpr ./config/rs6000/rs6000.md /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.md
*** ./config/rs6000/rs6000.md Sat Jul 31 15:44:42 1999
--- /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/rs6000.md Wed Sep 1 17:46:51 1999
***************
*** 7818,7824 ****
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
"{st|stw} %4,%3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
--- 7818,7824 ----
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[2]) == CALL_NORMAL || rs6000_is_longcall_p(operands[0], INTVAL(operands[2])))"
"{st|stw} %4,%3\;{l|lwz} %6,0(%0)\;{l|lwz} %4,4(%0)\;mt%7 %6\;{l|lwz} %5,8(%0)\;{brl|blrl}\;{l|lwz} %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
***************
*** 7833,7839 ****
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
"std %4,%3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
--- 7833,7839 ----
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[2]) == CALL_NORMAL || rs6000_is_longcall_p(operands[0], INTVAL(operands[2])))"
"std %4,%3\;ld %6,0(%0)\;ld %4,8(%0)\;mt%7 %6\;ld %5,16(%0)\;blrl\;ld %4,%3"
[(set_attr "type" "load")
(set_attr "length" "28")])
***************
*** 7849,7855 ****
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
"{st|stw} %5,%4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
--- 7849,7855 ----
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[3]) == CALL_NORMAL || rs6000_is_longcall_p(operands[1], INTVAL(operands[3])))"
"{st|stw} %5,%4\;{l|lwz} %7,0(%1)\;{l|lwz} %5,4(%1)\;mt%8 %7\;{l|lwz} %6,8(%1)\;{brl|blrl}\;{l|lwz} %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
***************
*** 7865,7871 ****
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
"std %5,%4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
--- 7865,7871 ----
(clobber (match_scratch:SI 7 "=&r"))
(clobber (match_scratch:SI 8 "=l"))]
"TARGET_64BIT && DEFAULT_ABI == ABI_AIX
! && (INTVAL (operands[3]) == CALL_NORMAL || rs6000_is_longcall_p(operands[1], INTVAL(operands[3])))"
"std %5,%4\;ld %7,0(%1)\;ld %5,8(%1)\;mt%8 %7\;ld %6,16(%1)\;blrl\;ld %5,%4"
[(set_attr "type" "load")
(set_attr "length" "28")])
***************
*** 7893,7899 ****
(clobber (match_scratch:SI 5 "=&r"))
(clobber (match_scratch:SI 6 "=l"))]
"DEFAULT_ABI == ABI_NT
! && (INTVAL (operands[2]) == CALL_NORMAL || (INTVAL (operands[2]) & CALL_LONG) != 0)"
"{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
[(set_attr "type" "load")
(set_attr "length" "24")])
--- 7893,7899 ----
(clobber (match_scratch:SI 5 "=&r"))
(clobber (match_scratch:SI 6 "=l"))]
"DEFAULT_ABI == ABI_NT
! && (INTVAL (operands[2]) == CALL_NORMAL || rs6000_is_longcall_p(operands[0], INTVAL(operands[2])))"
"{st|stw} %4,%a3\;{l|lwz} %5,0(%0)\;{l|lwz} %4,4(%0)\;mt%6 %5\;{brl|blrl}\;{l|lwz} %4,%a3"
[(set_attr "type" "load")
(set_attr "length" "24")])
***************
*** 7908,7914 ****
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_NT
! && (INTVAL (operands[3]) == CALL_NORMAL || (INTVAL (operands[3]) & CALL_LONG) != 0)"
"{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
[(set_attr "type" "load")
(set_attr "length" "24")])
--- 7908,7914 ----
(clobber (match_scratch:SI 6 "=&r"))
(clobber (match_scratch:SI 7 "=l"))]
"DEFAULT_ABI == ABI_NT
! && (INTVAL (operands[3]) == CALL_NORMAL || rs6000_is_longcall_p(operands[1], INTVAL(operands[3])))"
"{st|stw} %5,%a4\;{l|lwz} %6,0(%1)\;{l|lwz} %5,4(%1)\;mt%7 %6\;{brl|blrl}\;{l|lwz} %5,%a4"
[(set_attr "type" "load")
(set_attr "length" "24")])
***************
*** 7966,7971 ****
--- 7966,7972 ----
""
"
{
+ int is_longcall;
if (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != CONST_INT)
abort ();
***************
*** 7979,7988 ****
operands[2] = GEN_INT ((int)CALL_NORMAL);
}
if (GET_CODE (operands[0]) != SYMBOL_REF
! || (INTVAL (operands[2]) & CALL_LONG) != 0)
{
! if (INTVAL (operands[2]) & CALL_LONG)
operands[0] = rs6000_longcall_ref (operands[0]);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
--- 7980,7990 ----
operands[2] = GEN_INT ((int)CALL_NORMAL);
}
+ is_longcall = rs6000_is_longcall_p (operands[0], INTVAL (operands[2]));
if (GET_CODE (operands[0]) != SYMBOL_REF
! || is_longcall)
{
! if (is_longcall)
operands[0] = rs6000_longcall_ref (operands[0]);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
***************
*** 8028,8033 ****
--- 8030,8036 ----
""
"
{
+ int is_longcall;
if (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != CONST_INT)
abort ();
***************
*** 8040,8050 ****
operands[1] = rs6000_dll_import_ref (operands[1]);
operands[3] = GEN_INT ((int)CALL_NORMAL);
}
!
if (GET_CODE (operands[1]) != SYMBOL_REF
! || (INTVAL (operands[3]) & CALL_LONG) != 0)
{
! if (INTVAL (operands[3]) & CALL_LONG)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
--- 8043,8053 ----
operands[1] = rs6000_dll_import_ref (operands[1]);
operands[3] = GEN_INT ((int)CALL_NORMAL);
}
! is_longcall = rs6000_is_longcall_p (operands[1], INTVAL (operands[3]));
if (GET_CODE (operands[1]) != SYMBOL_REF
! || is_longcall)
{
! if (is_longcall)
operands[1] = rs6000_longcall_ref (operands[1]);
if (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_AIX_NODESC || DEFAULT_ABI == ABI_SOLARIS)
***************
*** 8095,8101 ****
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
! "(INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
--- 8098,8104 ----
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
! "!rs6000_is_longcall_p(operands[0], INTVAL(operands[2]))"
"*
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
***************
*** 8114,8120 ****
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
! "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
--- 8117,8123 ----
(match_operand 1 "" "g,g"))
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
! "TARGET_64BIT && !rs6000_is_longcall_p(operands[0], INTVAL(operands[2]))"
"*
{
if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
***************
*** 8134,8140 ****
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
! "(INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
--- 8137,8143 ----
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
! "!rs6000_is_longcall_p(operands[1], INTVAL(operands[3]))"
"*
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
***************
*** 8155,8161 ****
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
! "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
--- 8158,8164 ----
(match_operand 2 "" "g,g")))
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
! "TARGET_64BIT && !rs6000_is_longcall_p(operands[1], INTVAL(operands[3]))"
"*
{
if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
***************
*** 8182,8188 ****
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
/* Indirect calls should go through call_indirect */
--- 8185,8191 ----
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && !rs6000_is_longcall_p(operands[0], INTVAL(operands[2]))"
"*
{
/* Indirect calls should go through call_indirect */
***************
*** 8206,8212 ****
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
/* Indirect calls should go through call_indirect */
--- 8209,8215 ----
(use (match_operand:SI 2 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 3 "=l,l"))]
"TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && !rs6000_is_longcall_p(operands[0], INTVAL(operands[2]))"
"*
{
/* Indirect calls should go through call_indirect */
***************
*** 8230,8236 ****
(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_SOLARIS)
! && (INTVAL (operands[2]) & CALL_LONG) == 0"
"*
{
/* Indirect calls should go through call_indirect */
--- 8233,8239 ----
(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_SOLARIS)
! && !rs6000_is_longcall_p(operands[0], INTVAL(operands[2]))"
"*
{
/* Indirect calls should go through call_indirect */
***************
*** 8255,8261 ****
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
/* This should be handled by call_value_indirect */
--- 8258,8264 ----
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && !rs6000_is_longcall_p(operands[1], INTVAL(operands[3]))"
"*
{
/* This should be handled by call_value_indirect */
***************
*** 8280,8286 ****
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
/* This should be handled by call_value_indirect */
--- 8283,8289 ----
(use (match_operand:SI 3 "immediate_operand" "O,n"))
(clobber (match_scratch:SI 4 "=l,l"))]
"TARGET_64BIT && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_NT)
! && !rs6000_is_longcall_p(operands[1], INTVAL(operands[3]))"
"*
{
/* This should be handled by call_value_indirect */
***************
*** 8305,8311 ****
(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_SOLARIS)
! && (INTVAL (operands[3]) & CALL_LONG) == 0"
"*
{
/* This should be handled by call_value_indirect */
--- 8308,8314 ----
(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_SOLARIS)
! && !rs6000_is_longcall_p(operands[1], INTVAL(operands[3]))"
"*
{
/* This should be handled by call_value_indirect */
diff -N -cpr ./config/rs6000/sysv4.h /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/sysv4.h
*** ./config/rs6000/sysv4.h Sat Jul 31 15:44:55 1999
--- /view/mrs.t2p3a/wind/river/host/src/gnu/gcc/config/rs6000/sysv4.h Wed Sep 8 12:33:17 1999
*************** do { \
*** 1112,1118 ****
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \
! %{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT}"
#undef CPP_SYSV_DEFAULT_SPEC
#define CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
--- 1112,1119 ----
%{mcall-sysv: -D_CALL_SYSV} %{mcall-nt: -D_CALL_NT} \
%{mcall-aix: -D_CALL_AIX} %{mcall-aixdesc: -D_CALL_AIX -D_CALL_AIXDESC} \
%{!mcall-sysv: %{!mcall-aix: %{!mcall-aixdesc: %{!mcall-nt: %(cpp_sysv_default) }}}} \
! %{msoft-float: -D_SOFT_FLOAT} %{mcpu=403: -D_SOFT_FLOAT} \
! %{mcpu=860: -D_SOFT_FLOAT}"
#undef CPP_SYSV_DEFAULT_SPEC
#define CPP_SYSV_DEFAULT_SPEC "-D_CALL_SYSV"
diff -N -cpr ./varasm.c ./varasm.c
*** ./varasm.c Sat Jul 31 15:16:25 1999
--- ./varasm.c Wed Sep 1 17:47:23 1999
*************** exception_section ()
*** 470,475 ****
--- 470,487 ----
#endif
}
+
+ /* Optionally record the information that a function has been defined
+ in this file */
+
+ void
+ mark_fn_defined_in_this_file (tree decl)
+ {
+ #ifdef MARK_FN_DEFINED_IN_THIS_FILE
+ MARK_FN_DEFINED_IN_THIS_FILE (decl);
+ #endif
+ }
+
/* Create the rtl to represent a function, for a function definition.
DECL is a FUNCTION_DECL node which describes which function.
The rtl is stored into DECL. */
*************** make_function_rtl (decl)
*** 520,525 ****
--- 532,543 ----
#ifdef ENCODE_SECTION_INFO
ENCODE_SECTION_INFO (decl);
#endif
+
+ /* non public functions must be defined in this file so
+ we mark them as such */
+ if (!TREE_PUBLIC (decl))
+ mark_fn_defined_in_this_file (decl);
+
}
else
{
diff -N -cpr ./output.h ./output.h
*** ./output.h Sat Jul 31 15:12:02 1999
--- ./output.h Wed Sep 1 17:47:17 1999
*************** extern void function_section PROTO((tre
*** 170,175 ****
--- 170,179 ----
/* Tell assembler to switch to the section for the exception table. */
extern void exception_section PROTO((void));
+ /* Optionally record the information that a function has been defined
+ in this file */
+ extern void mark_fn_defined_in_this_file (tree decl);
+
/* Create the rtl to represent a function, for a function definition.
DECL is a FUNCTION_DECL node which describes which function.
The rtl is stored into DECL. */
diff -N -cpr ./c-decl.c ./c-decl.c
*** ./c-decl.c Sat Jul 31 14:58:56 1999
--- ./c-decl.c Wed Sep 1 17:46:23 1999
*************** finish_function (nested)
*** 7267,7272 ****
--- 7267,7277 ----
/* Run the optimizers and output the assembler code for this function. */
rest_of_compilation (fndecl);
+ /* If we're sure this function is defined in this file then mark it
+ as such */
+ if (TREE_ASM_WRITTEN (fndecl))
+ mark_fn_defined_in_this_file (fndecl);
+
current_function_returns_null |= can_reach_end;
if (warn_missing_noreturn
diff -N -cpr ./cp/decl.c ./cp/decl.c
*** ./cp/decl.c Sat Jul 31 15:52:22 1999
--- ./cp/decl.c Wed Sep 1 17:46:58 1999
*************** finish_function (lineno, flags, nested)
*** 14471,14476 ****
--- 14471,14481 ----
flag_keep_inline_functions = saved_flag_keep_inline_functions;
+ /* If we're sure this function is defined in this file then mark it
+ as such */
+ if (TREE_ASM_WRITTEN (fndecl))
+ mark_fn_defined_in_this_file (fndecl);
+
if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
{
/* Set DECL_EXTERNAL so that assemble_external will be called as
diff -N -cpr ./c-pragma.c ./c-pragma.c
*** ./c-pragma.c Sat Jul 31 15:00:13 1999
--- ./c-pragma.c Wed Sep 1 17:46:29 1999
*************** handle_pragma_token (string, token)
*** 301,306 ****
--- 301,311 ----
ret_val = 1; /* Ignore the pragma. */
break;
#endif /* HANDLE_PRAGMA_WEAK */
+ #ifdef HANDLE_OTHER_PRAGMA_TOKEN
+ case ps_other:
+ HANDLE_OTHER_PRAGMA_TOKEN (string, token);
+ break;
+ #endif /* HANDLE_OTHER_PRAGMA_TOKEN */
}
type = state = ps_start;
*************** handle_pragma_token (string, token)
*** 339,347 ****
#ifdef HANDLE_PRAGMA_WEAK
if (strcmp (string, "weak") == 0)
type = state = ps_weak;
#endif
break;
!
#ifdef HANDLE_PRAGMA_WEAK
case ps_weak:
name = permalloc (strlen (string) + 1);
--- 344,365 ----
#ifdef HANDLE_PRAGMA_WEAK
if (strcmp (string, "weak") == 0)
type = state = ps_weak;
+ #endif
+ #ifdef HANDLE_OTHER_PRAGMA_TOKEN
+ /* If we haven't already handled it then do so now */
+ if (type == ps_done)
+ {
+ HANDLE_OTHER_PRAGMA_TOKEN (string, token);
+ type = state = ps_other;
+ }
#endif
break;
! #ifdef HANDLE_OTHER_PRAGMA_TOKEN
! case ps_other:
! HANDLE_OTHER_PRAGMA_TOKEN (string, token);
! break;
! #endif
!
#ifdef HANDLE_PRAGMA_WEAK
case ps_weak:
name = permalloc (strlen (string) + 1);
diff -N -cpr ./c-pragma.h ./c-pragma.h
*** ./c-pragma.h Sat Jul 31 15:00:19 1999
--- ./c-pragma.h Wed Sep 1 17:46:33 1999
*************** extern int add_weak PROTO((char *, char
*** 69,80 ****
--- 69,94 ----
#define HANDLE_GENERIC_PRAGMAS 1
#endif
+ /* Define HANDLE_OTHER_PRAGMA_TOKEN(string, token) if you want
+ to handle pragmas other than align and weak. When handle_pragma_token
+ comes across a pragma it doesn't understand, it will delegate
+ responsibility for handling it to HANDLE_OTHER_PRAGMA_TOKEN (if defined),
+ passing it the current token (token) and its printable form (string).
+ The latter should implement its own state machine along the lines of the
+ one in handle_pragma_token. */
+
+ #if defined HANDLED_OTHER_PRAGMA_TOKEN
+ #define HANDLE_GENERIC_PRAGMAS 1
+ #endif
#ifdef HANDLE_GENERIC_PRAGMAS
enum pragma_state
{
ps_start,
ps_done,
+ #ifdef HANDLE_OTHER_PRAGMA_TOKEN
+ ps_other,
+ #endif
#ifdef HANDLE_PRAGMA_WEAK
ps_weak,
ps_name,
-----