mips.c (mips_attribute_table): Add "near" and "far" function attributes, "far" being an alias for "long_call".
2007-05-25 Sandra Loosemore <sandra@codesourcery.com> Nigel Stephens <nigel@mips.com> gcc/ * config/mips/mips.c (mips_attribute_table): Add "near" and "far" function attributes, "far" being an alias for "long_call". (TARGET_COMP_TYPE_ATTRIBUTES): Define as mips_comp_type_attributes. (mips_near_type_p, mips_far_type_p): New. (mips_comp_type_attributes): New function to check that attributes attached to a function type are compatible. (mips_output_mi_thunk): Test SYMBOL_REF_LONG_CALL_P() rather than TARGET_LONG_CALLS when deciding whether we can do a direct sibcall to the target function of the thunk. (mips_encode_section_info): Check for "near" and "far" function attributes, and always set the SYMBOL_FLAG_LONG_CALL bit explicitly. * config/mips/predicates.md (const_call_insn_operand): Test only SYMBOL_REF_LONG_CALL_P() and not TARGET_LONG_CALLS. * doc/extend.texi (Function Attributes): Document MIPS "near" and "far" attributes. * testsuite/gcc.target/mips/near-far-1.c: New test case. * testsuite/gcc.target/mips/near-far-2.c: New test case. * testsuite/gcc.target/mips/near-far-3.c: New test case. * testsuite/gcc.target/mips/near-far-4.c: New test case. Co-Authored-By: Nigel Stephens <nigel@mips.com> From-SVN: r125086
This commit is contained in:
parent
8536ebb582
commit
cd3a59b38e
|
@ -1,3 +1,29 @@
|
|||
2007-05-25 Sandra Loosemore <sandra@codesourcery.com>
|
||||
Nigel Stephens <nigel@mips.com>
|
||||
|
||||
* config/mips/mips.c (mips_attribute_table): Add "near" and "far"
|
||||
function attributes, "far" being an alias for "long_call".
|
||||
(TARGET_COMP_TYPE_ATTRIBUTES): Define as mips_comp_type_attributes.
|
||||
(mips_near_type_p, mips_far_type_p): New.
|
||||
(mips_comp_type_attributes): New function to check that attributes
|
||||
attached to a function type are compatible.
|
||||
(mips_output_mi_thunk): Test SYMBOL_REF_LONG_CALL_P() rather than
|
||||
TARGET_LONG_CALLS when deciding whether we can do a direct sibcall
|
||||
to the target function of the thunk.
|
||||
(mips_encode_section_info): Check for "near" and "far" function
|
||||
attributes, and always set the SYMBOL_FLAG_LONG_CALL bit explicitly.
|
||||
|
||||
* config/mips/predicates.md (const_call_insn_operand): Test only
|
||||
SYMBOL_REF_LONG_CALL_P() and not TARGET_LONG_CALLS.
|
||||
|
||||
* doc/extend.texi (Function Attributes): Document MIPS "near" and
|
||||
"far" attributes.
|
||||
|
||||
* testsuite/gcc.target/mips/near-far-1.c: New test case.
|
||||
* testsuite/gcc.target/mips/near-far-2.c: New test case.
|
||||
* testsuite/gcc.target/mips/near-far-3.c: New test case.
|
||||
* testsuite/gcc.target/mips/near-far-4.c: New test case.
|
||||
|
||||
2007-05-25 Eric Christopher <echristo@apple.com>
|
||||
|
||||
* config.gcc: Add i386/t-fprules-softfp64 and soft-fp/t-softfp
|
||||
|
|
|
@ -411,6 +411,7 @@ static rtx mips_expand_builtin_compare (enum mips_builtin_type,
|
|||
static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
|
||||
static void mips_encode_section_info (tree, rtx, int);
|
||||
static void mips_extra_live_on_entry (bitmap);
|
||||
static int mips_comp_type_attributes (tree, tree);
|
||||
static int mips_mode_rep_extended (enum machine_mode, enum machine_mode);
|
||||
static bool mips_offset_within_alignment_p (rtx, HOST_WIDE_INT);
|
||||
|
||||
|
@ -685,6 +686,8 @@ const enum reg_class mips_regno_to_class[] =
|
|||
const struct attribute_spec mips_attribute_table[] =
|
||||
{
|
||||
{ "long_call", 0, 0, false, true, true, NULL },
|
||||
{ "far", 0, 0, false, true, true, NULL },
|
||||
{ "near", 0, 0, false, true, true, NULL },
|
||||
{ NULL, 0, 0, false, false, false, NULL }
|
||||
};
|
||||
|
||||
|
@ -1249,7 +1252,48 @@ static struct mips_rtx_cost_data const mips_rtx_cost_data[PROCESSOR_MAX] =
|
|||
#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
|
||||
#define TARGET_USE_ANCHORS_FOR_SYMBOL_P mips_use_anchors_for_symbol_p
|
||||
|
||||
#undef TARGET_COMP_TYPE_ATTRIBUTES
|
||||
#define TARGET_COMP_TYPE_ATTRIBUTES mips_comp_type_attributes
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
||||
/* Predicates to test for presence of "near" and "far"/"long_call"
|
||||
attributes on the given TYPE. */
|
||||
|
||||
static bool
|
||||
mips_near_type_p (tree type)
|
||||
{
|
||||
return lookup_attribute ("near", TYPE_ATTRIBUTES (type)) != NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
mips_far_type_p (tree type)
|
||||
{
|
||||
return (lookup_attribute ("long_call", TYPE_ATTRIBUTES (type)) != NULL
|
||||
|| lookup_attribute ("far", TYPE_ATTRIBUTES (type)) != NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Return 0 if the attributes for two types are incompatible, 1 if they
|
||||
are compatible, and 2 if they are nearly compatible (which causes a
|
||||
warning to be generated). */
|
||||
|
||||
static int
|
||||
mips_comp_type_attributes (tree type1, tree type2)
|
||||
{
|
||||
/* Check for mismatch of non-default calling convention. */
|
||||
if (TREE_CODE (type1) != FUNCTION_TYPE)
|
||||
return 1;
|
||||
|
||||
/* Disallow mixed near/far attributes. */
|
||||
if (mips_far_type_p (type1) && mips_near_type_p (type2))
|
||||
return 0;
|
||||
if (mips_near_type_p (type1) && mips_far_type_p (type2))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return true if SYMBOL_REF X is associated with a global symbol
|
||||
(in the STB_GLOBAL sense). */
|
||||
|
@ -7332,7 +7376,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
|
|||
/* Jump to the target function. Use a sibcall if direct jumps are
|
||||
allowed, otherwise load the address into a register first. */
|
||||
fnaddr = XEXP (DECL_RTL (function), 0);
|
||||
if (TARGET_MIPS16 || TARGET_USE_GOT || TARGET_LONG_CALLS)
|
||||
if (TARGET_MIPS16 || TARGET_USE_GOT || SYMBOL_REF_LONG_CALL_P (fnaddr))
|
||||
{
|
||||
/* This is messy. gas treats "la $25,foo" as part of a call
|
||||
sequence and may allow a global "foo" to be lazily bound.
|
||||
|
@ -11139,11 +11183,13 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
|
|||
{
|
||||
default_encode_section_info (decl, rtl, first);
|
||||
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL
|
||||
&& lookup_attribute ("long_call", TYPE_ATTRIBUTES (TREE_TYPE (decl))))
|
||||
if (TREE_CODE (decl) == FUNCTION_DECL)
|
||||
{
|
||||
rtx symbol = XEXP (rtl, 0);
|
||||
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
|
||||
|
||||
if ((TARGET_LONG_CALLS && !mips_near_type_p (TREE_TYPE (decl)))
|
||||
|| mips_far_type_p (TREE_TYPE (decl)))
|
||||
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,10 +113,10 @@
|
|||
&& !DECL_EXTERNAL (SYMBOL_REF_DECL (op))))
|
||||
return false;
|
||||
|
||||
/* If -mlong-calls, force all calls to use register addressing. Also,
|
||||
if this function has the long_call attribute, we must use register
|
||||
addressing. */
|
||||
return !TARGET_LONG_CALLS && !SYMBOL_REF_LONG_CALL_P (op);
|
||||
/* If -mlong-calls or if this function has an explicit long_call
|
||||
attribute, we must use register addressing. The
|
||||
SYMBOL_FLAG_LONG_CALL bit is set by mips_encode_section_info. */
|
||||
return !SYMBOL_REF_LONG_CALL_P (op);
|
||||
|
||||
case SYMBOL_GOT_DISP:
|
||||
/* Without explicit relocs, there is no special syntax for
|
||||
|
|
|
@ -2110,13 +2110,16 @@ PowerPC, the @code{#pragma longcall} setting.
|
|||
@xref{RS/6000 and PowerPC Options}, for more information on whether long
|
||||
calls are necessary.
|
||||
|
||||
@item long_call
|
||||
@item long_call/near/far
|
||||
@cindex indirect calls on MIPS
|
||||
This attribute specifies how a particular function is called on MIPS@.
|
||||
The attribute overrides the @option{-mlong-calls} (@pxref{MIPS Options})
|
||||
command line switch. This attribute causes the compiler to always call
|
||||
These attributes specify how a particular function is called on MIPS@.
|
||||
The attributes override the @option{-mlong-calls} (@pxref{MIPS Options})
|
||||
command-line switch. The @code{long_call} and @code{far} attributes are
|
||||
synonyms, and cause the compiler to always call
|
||||
the function by first loading its address into a register, and then using
|
||||
the contents of that register.
|
||||
the contents of that register. The @code{near} attribute has the opposite
|
||||
effect; it specifies that non-PIC calls should be made using the more
|
||||
efficient @code{jal} instruction.
|
||||
|
||||
@item malloc
|
||||
@cindex @code{malloc} attribute
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-mlong-calls" } */
|
||||
/* { dg-require-effective-target nonpic } */
|
||||
|
||||
extern int long_call_func () __attribute__((long_call));
|
||||
extern int far_func () __attribute__((far));
|
||||
extern int near_func () __attribute__((near));
|
||||
extern int normal_func ();
|
||||
|
||||
int test ()
|
||||
{
|
||||
return (long_call_func ()
|
||||
+ far_func ()
|
||||
+ near_func ()
|
||||
+ normal_func ());
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tjal\tlong_call_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tjal\tfar_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tjal\tnear_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tjal\tnormal_func\n" } } */
|
|
@ -0,0 +1,21 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-mno-long-calls" } */
|
||||
/* { dg-require-effective-target nonpic } */
|
||||
|
||||
extern int long_call_func () __attribute__((long_call));
|
||||
extern int far_func () __attribute__((far));
|
||||
extern int near_func () __attribute__((near));
|
||||
extern int normal_func ();
|
||||
|
||||
int test ()
|
||||
{
|
||||
return (long_call_func ()
|
||||
+ far_func ()
|
||||
+ near_func ()
|
||||
+ normal_func ());
|
||||
}
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tjal\tlong_call_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tjal\tfar_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tjal\tnear_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tjal\tnormal_func\n" } } */
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-mlong-calls -O2 -mno-mips16" } */
|
||||
/* { dg-require-effective-target nonpic } */
|
||||
|
||||
extern int long_call_func () __attribute__((long_call));
|
||||
extern int far_func () __attribute__((far));
|
||||
extern int near_func () __attribute__((near));
|
||||
extern int normal_func ();
|
||||
|
||||
int test1 () { return long_call_func (); }
|
||||
int test2 () { return far_func (); }
|
||||
int test3 () { return near_func (); }
|
||||
int test4 () { return normal_func (); }
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tj\tnear_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tj\tnormal_func\n" } } */
|
|
@ -0,0 +1,18 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-mips-options "-mno-long-calls -O2 -mno-mips16" } */
|
||||
/* { dg-require-effective-target nonpic } */
|
||||
|
||||
extern int long_call_func () __attribute__((long_call));
|
||||
extern int far_func () __attribute__((far));
|
||||
extern int near_func () __attribute__((near));
|
||||
extern int normal_func ();
|
||||
|
||||
int test1 () { return long_call_func (); }
|
||||
int test2 () { return far_func (); }
|
||||
int test3 () { return near_func (); }
|
||||
int test4 () { return normal_func (); }
|
||||
|
||||
/* { dg-final { scan-assembler-not "\tj\tlong_call_func\n" } } */
|
||||
/* { dg-final { scan-assembler-not "\tj\tfar_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tj\tnear_func\n" } } */
|
||||
/* { dg-final { scan-assembler "\tj\tnormal_func\n" } } */
|
Loading…
Reference in New Issue