Commit 9a6dfb47 by Richard Sandiford Committed by Richard Sandiford

mips.h (SYMBOL_FLAG_MIPS16_FUNC): Delete.

gcc/
2007-09-13  Richard Sandiford  <richard@codesourcery.com>
	    Sandra Loosemore <sandra@codesourcery.com>

	* config/mips/mips.h (SYMBOL_FLAG_MIPS16_FUNC): Delete.
	(SYMBOL_REF_MIPS16_FUNC_P): Delete.
	* config/mips/mips.c (mips_attribute_table): Turn mips16 and
	nomips16 into decl attributes.
	(TARGET_INSERT_ATTRIBUTES): Override.
	(TARGET_MERGE_DECL_ATTRIBUTES): Likewise.
	(TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): Always return true.
	(mips_mips16_type_p, mips_nomips16_type_p): Delete in favor of...
	(mips_mips16_decl_p, mips_nomips16_decl_p): ...these new functions.
	(mips_comp_type_attributes): Remove mips16 and nomips16 handling.
	(mips_use_mips16_mode_p): Reimplement as a function that takes
	a decl and considers only decl attributes.  If the decl is nested
	function, use its parent attributes.
	(mips_function_ok_for_sibcall): Use mips_use_mips16_mode_p
	instead of SYMBOL_REF_MIPS16_FUNC_P.
	(mips_set_mips16_mode): Move call to sorry here from old
	mips_use_mips16_mode_p.
	(mflip_mips16_entry): New structure.
	(mflip_mips16_htab): New variable.
	(mflip_mips16_htab_hash, mflip_mips16_htab_eq): New functions.
	(mflip_mips16_use_mips16_p, mips_insert_attributes): Likewise.
	(mips_merge_decl_attributes): New function.
	(mips_set_current_function): Reinstate call to mips_set_mips16_mode.
	Use mips_use_mips16_mode_p.
	(mips_output_mi_thunk): Use mips_use_mips16_mode_p instead of
	SYMBOL_REF_MIPS16_FUNC_P.
	(mips_encode_section_info): Don't set SYMBOL_FLAG_MIPS16_FUNC.

gcc/testsuite/
	* gcc.dg/gcc-have-sync-compare-and-swap.c: Skip for -mflip-mips16.
	* gcc.target/mips/mips16-attributes-2.c: New test.
	* gcc.target/mips/mips16-attributes-3.c: Likewise.
	* gcc.target/mips/args-3.c: Skip for -mflip-mips16.  Do not use the
	hard-float asm when __mips16 is defined.
	* gcc.target/mips/atomic-memory-1.c (main): Add a nomips16 attribute.
	* gcc.target/mips/atomic-memory-2.c (main): Likewise.
	* gcc.target/mips/fpcmp-1.c (f1, f2): Likewise.
	* gcc.target/mips/fpcmp-2.c (f1, f2): Likewise.
	* gcc.target/mips/neg-abs-1.c (f1, f2, d1, f2): Likewise.
	* gcc.target/mips/pr26765.c (foo): Likewise.
	* gcc.target/mips/gcc-have-sync-compare-and-swap-1.c: Run for all
	targets, use dg-mips-options instead of dg-options, and use -mgp32
	to force 32-bit mode.
	* gcc.target/mips/gcc-have-sync-compare-and-swap-2.c: Likewise -mgp64
	and 64-bit mode.
	* gcc.target/mips/mips.exp (is_gp32_flag): Return true for -mips32*.

Co-Authored-By: Sandra Loosemore <sandra@codesourcery.com>

From-SVN: r128460
parent 0ad7e054
2007-09-13 Richard Sandiford <richard@codesourcery.com> 2007-09-13 Richard Sandiford <richard@codesourcery.com>
Sandra Loosemore <sandra@codesourcery.com>
* config/mips/mips.h (SYMBOL_FLAG_MIPS16_FUNC): Delete.
(SYMBOL_REF_MIPS16_FUNC_P): Delete.
* config/mips/mips.c (mips_attribute_table): Turn mips16 and
nomips16 into decl attributes.
(TARGET_INSERT_ATTRIBUTES): Override.
(TARGET_MERGE_DECL_ATTRIBUTES): Likewise.
(TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P): Always return true.
(mips_mips16_type_p, mips_nomips16_type_p): Delete in favor of...
(mips_mips16_decl_p, mips_nomips16_decl_p): ...these new functions.
(mips_comp_type_attributes): Remove mips16 and nomips16 handling.
(mips_use_mips16_mode_p): Reimplement as a function that takes
a decl and considers only decl attributes. If the decl is nested
function, use its parent attributes.
(mips_function_ok_for_sibcall): Use mips_use_mips16_mode_p
instead of SYMBOL_REF_MIPS16_FUNC_P.
(mips_set_mips16_mode): Move call to sorry here from old
mips_use_mips16_mode_p.
(mflip_mips16_entry): New structure.
(mflip_mips16_htab): New variable.
(mflip_mips16_htab_hash, mflip_mips16_htab_eq): New functions.
(mflip_mips16_use_mips16_p, mips_insert_attributes): Likewise.
(mips_merge_decl_attributes): New function.
(mips_set_current_function): Reinstate call to mips_set_mips16_mode.
Use mips_use_mips16_mode_p.
(mips_output_mi_thunk): Use mips_use_mips16_mode_p instead of
SYMBOL_REF_MIPS16_FUNC_P.
(mips_encode_section_info): Don't set SYMBOL_FLAG_MIPS16_FUNC.
2007-09-13 Richard Sandiford <richard@codesourcery.com>
* c-parser.c (c_parser_struct_declaration): Check for a null return. * c-parser.c (c_parser_struct_declaration): Check for a null return.
...@@ -426,6 +426,8 @@ static void mips_encode_section_info (tree, rtx, int); ...@@ -426,6 +426,8 @@ static void mips_encode_section_info (tree, rtx, int);
static void mips_extra_live_on_entry (bitmap); static void mips_extra_live_on_entry (bitmap);
static int mips_comp_type_attributes (const_tree, const_tree); static int mips_comp_type_attributes (const_tree, const_tree);
static void mips_set_mips16_mode (int); static void mips_set_mips16_mode (int);
static void mips_insert_attributes (tree, tree *);
static tree mips_merge_decl_attributes (tree, tree);
static void mips_set_current_function (tree); static void mips_set_current_function (tree);
static int mips_mode_rep_extended (enum machine_mode, enum machine_mode); static int mips_mode_rep_extended (enum machine_mode, enum machine_mode);
static bool mips_offset_within_alignment_p (rtx, HOST_WIDE_INT); static bool mips_offset_within_alignment_p (rtx, HOST_WIDE_INT);
...@@ -734,9 +736,13 @@ const struct attribute_spec mips_attribute_table[] = ...@@ -734,9 +736,13 @@ const struct attribute_spec mips_attribute_table[] =
{ "long_call", 0, 0, false, true, true, NULL }, { "long_call", 0, 0, false, true, true, NULL },
{ "far", 0, 0, false, true, true, NULL }, { "far", 0, 0, false, true, true, NULL },
{ "near", 0, 0, false, true, true, NULL }, { "near", 0, 0, false, true, true, NULL },
/* Switch MIPS16 ASE on and off per-function. */ /* Switch MIPS16 ASE on and off per-function. We would really like
{ "mips16", 0, 0, false, true, true, NULL }, to make these type attributes, but GCC doesn't provide the hooks
{ "nomips16", 0, 0, false, true, true, NULL }, we need to support the right conversion rules. As declaration
attributes, they affect code generation but don't carry other
semantics. */
{ "mips16", 0, 0, true, false, false, NULL },
{ "nomips16", 0, 0, true, false, false, NULL },
{ NULL, 0, 0, false, false, false, NULL } { NULL, 0, 0, false, false, false, NULL }
}; };
...@@ -1268,6 +1274,10 @@ static const unsigned char mips16e_save_restore_regs[] = { ...@@ -1268,6 +1274,10 @@ static const unsigned char mips16e_save_restore_regs[] = {
#undef TARGET_FUNCTION_OK_FOR_SIBCALL #undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall #define TARGET_FUNCTION_OK_FOR_SIBCALL mips_function_ok_for_sibcall
#undef TARGET_INSERT_ATTRIBUTES
#define TARGET_INSERT_ATTRIBUTES mips_insert_attributes
#undef TARGET_MERGE_DECL_ATTRIBUTES
#define TARGET_MERGE_DECL_ATTRIBUTES mips_merge_decl_attributes
#undef TARGET_SET_CURRENT_FUNCTION #undef TARGET_SET_CURRENT_FUNCTION
#define TARGET_SET_CURRENT_FUNCTION mips_set_current_function #define TARGET_SET_CURRENT_FUNCTION mips_set_current_function
...@@ -1352,6 +1362,10 @@ static const unsigned char mips16e_save_restore_regs[] = { ...@@ -1352,6 +1362,10 @@ static const unsigned char mips16e_save_restore_regs[] = {
#undef TARGET_ATTRIBUTE_TABLE #undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE mips_attribute_table #define TARGET_ATTRIBUTE_TABLE mips_attribute_table
/* All our function attributes are related to how out-of-line copies should
be compiled or called. They don't in themselves prevent inlining. */
#undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P hook_bool_const_tree_true
#undef TARGET_EXTRA_LIVE_ON_ENTRY #undef TARGET_EXTRA_LIVE_ON_ENTRY
#define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry #define TARGET_EXTRA_LIVE_ON_ENTRY mips_extra_live_on_entry
...@@ -1395,15 +1409,15 @@ mips_far_type_p (const_tree type) ...@@ -1395,15 +1409,15 @@ mips_far_type_p (const_tree type)
/* Similar predicates for "mips16"/"nomips16" attributes. */ /* Similar predicates for "mips16"/"nomips16" attributes. */
static bool static bool
mips_mips16_type_p (const_tree type) mips_mips16_decl_p (const_tree decl)
{ {
return lookup_attribute ("mips16", TYPE_ATTRIBUTES (type)) != NULL; return lookup_attribute ("mips16", DECL_ATTRIBUTES (decl)) != NULL;
} }
static bool static bool
mips_nomips16_type_p (const_tree type) mips_nomips16_decl_p (const_tree decl)
{ {
return lookup_attribute ("nomips16", TYPE_ATTRIBUTES (type)) != NULL; return lookup_attribute ("nomips16", DECL_ATTRIBUTES (decl)) != NULL;
} }
/* Return 0 if the attributes for two types are incompatible, 1 if they /* Return 0 if the attributes for two types are incompatible, 1 if they
...@@ -1423,11 +1437,6 @@ mips_comp_type_attributes (const_tree type1, const_tree type2) ...@@ -1423,11 +1437,6 @@ mips_comp_type_attributes (const_tree type1, const_tree type2)
if (mips_near_type_p (type1) && mips_far_type_p (type2)) if (mips_near_type_p (type1) && mips_far_type_p (type2))
return 0; return 0;
/* Mips16/nomips16 attributes must match exactly. */
if (mips_nomips16_type_p (type1) != mips_nomips16_type_p (type2)
|| mips_mips16_type_p (type1) != mips_mips16_type_p (type2))
return 0;
return 1; return 1;
} }
...@@ -4120,6 +4129,27 @@ mips_gen_conditional_trap (rtx *operands) ...@@ -4120,6 +4129,27 @@ mips_gen_conditional_trap (rtx *operands)
operands[1])); operands[1]));
} }
/* Return true if function DECL is a MIPS16 function. Return the ambient
setting if DECL is null. */
static bool
mips_use_mips16_mode_p (tree decl)
{
if (decl)
{
/* Nested functions must use the same frame pointer as their
parent and must therefore use the same ISA mode. */
tree parent = decl_function_context (decl);
if (parent)
decl = parent;
if (mips_mips16_decl_p (decl))
return true;
if (mips_nomips16_decl_p (decl))
return false;
}
return mips_base_mips16;
}
/* Return true if calls to X can use R_MIPS_CALL* relocations. */ /* Return true if calls to X can use R_MIPS_CALL* relocations. */
static bool static bool
...@@ -4223,7 +4253,7 @@ mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED) ...@@ -4223,7 +4253,7 @@ mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
/* We can't do a sibcall if the called function is a MIPS16 function /* We can't do a sibcall if the called function is a MIPS16 function
because there is no direct "jx" instruction equivalent to "jalx" to because there is no direct "jx" instruction equivalent to "jalx" to
switch the ISA mode. */ switch the ISA mode. */
if (decl && SYMBOL_REF_MIPS16_FUNC_P (XEXP (DECL_RTL (decl), 0))) if (mips_use_mips16_mode_p (decl))
return false; return false;
/* Otherwise OK. */ /* Otherwise OK. */
...@@ -5666,6 +5696,9 @@ mips_set_mips16_mode (int mips16_p) ...@@ -5666,6 +5696,9 @@ mips_set_mips16_mode (int mips16_p)
of lw and sw instead. */ of lw and sw instead. */
targetm.min_anchor_offset = 0; targetm.min_anchor_offset = 0;
targetm.max_anchor_offset = 127; targetm.max_anchor_offset = 127;
if (flag_pic || TARGET_ABICALLS)
sorry ("MIPS16 PIC");
} }
else else
{ {
...@@ -5703,12 +5736,130 @@ mips_set_mips16_mode (int mips16_p) ...@@ -5703,12 +5736,130 @@ mips_set_mips16_mode (int mips16_p)
was_mips16_p = TARGET_MIPS16; was_mips16_p = TARGET_MIPS16;
} }
/* Use a hash table to keep track of implicit mips16/nomips16 attributes
for -mflip_mips16. It maps decl names onto a boolean mode setting. */
struct mflip_mips16_entry GTY (()) {
const char *name;
bool mips16_p;
};
static GTY ((param_is (struct mflip_mips16_entry))) htab_t mflip_mips16_htab;
/* Hash table callbacks for mflip_mips16_htab. */
static hashval_t
mflip_mips16_htab_hash (const void *entry)
{
return htab_hash_string (((const struct mflip_mips16_entry *) entry)->name);
}
static int
mflip_mips16_htab_eq (const void *entry, const void *name)
{
return strcmp (((const struct mflip_mips16_entry *) entry)->name,
(const char *) name) == 0;
}
/* DECL is a function that needs a default "mips16" or "nomips16" attribute
for -mflip-mips16. Return true if it should use "mips16" and false if
it should use "nomips16". */
static bool
mflip_mips16_use_mips16_p (tree decl)
{
struct mflip_mips16_entry *entry;
const char *name;
hashval_t hash;
void **slot;
/* Use the opposite of the command-line setting for anonymous decls. */
if (!DECL_NAME (decl))
return !mips_base_mips16;
if (!mflip_mips16_htab)
mflip_mips16_htab = htab_create_ggc (37, mflip_mips16_htab_hash,
mflip_mips16_htab_eq, NULL);
name = IDENTIFIER_POINTER (DECL_NAME (decl));
hash = htab_hash_string (name);
slot = htab_find_slot_with_hash (mflip_mips16_htab, name, hash, INSERT);
entry = (struct mflip_mips16_entry *) *slot;
if (!entry)
{
mips16_flipper = !mips16_flipper;
entry = GGC_NEW (struct mflip_mips16_entry);
entry->name = name;
entry->mips16_p = mips16_flipper ? !mips_base_mips16 : mips_base_mips16;
*slot = entry;
}
return entry->mips16_p;
}
/* Implement TARGET_INSERT_ATTRIBUTES. */
static void
mips_insert_attributes (tree decl, tree *attributes)
{
const char *name;
bool mips16_p, nomips16_p;
/* Check for "mips16" and "nomips16" attributes. */
mips16_p = lookup_attribute ("mips16", *attributes) != NULL;
nomips16_p = lookup_attribute ("nomips16", *attributes) != NULL;
if (TREE_CODE (decl) != FUNCTION_DECL)
{
if (mips16_p)
error ("%qs attribute only applies to functions", "mips16");
if (nomips16_p)
error ("%qs attribute only applies to functions", "nomips16");
}
else
{
mips16_p |= mips_mips16_decl_p (decl);
nomips16_p |= mips_nomips16_decl_p (decl);
if (mips16_p || nomips16_p)
{
/* DECL cannot be simultaneously mips16 and nomips16. */
if (mips16_p && nomips16_p)
error ("%qs cannot have both %<mips16%> and "
"%<nomips16%> attributes",
IDENTIFIER_POINTER (DECL_NAME (decl)));
}
else if (TARGET_FLIP_MIPS16 && !DECL_ARTIFICIAL (decl))
{
/* Implement -mflip-mips16. If DECL has neither a "nomips16" nor a
"mips16" attribute, arbitrarily pick one. We must pick the same
setting for duplicate declarations of a function. */
name = mflip_mips16_use_mips16_p (decl) ? "mips16" : "nomips16";
*attributes = tree_cons (get_identifier (name), NULL, *attributes);
}
}
}
/* Implement TARGET_MERGE_DECL_ATTRIBUTES. */
static tree
mips_merge_decl_attributes (tree olddecl, tree newdecl)
{
/* The decls' "mips16" and "nomips16" attributes must match exactly. */
if (mips_mips16_decl_p (olddecl) != mips_mips16_decl_p (newdecl))
error ("%qs redeclared with conflicting %qs attributes",
IDENTIFIER_POINTER (DECL_NAME (newdecl)), "mips16");
if (mips_nomips16_decl_p (olddecl) != mips_nomips16_decl_p (newdecl))
error ("%qs redeclared with conflicting %qs attributes",
IDENTIFIER_POINTER (DECL_NAME (newdecl)), "nomips16");
return merge_attributes (DECL_ATTRIBUTES (olddecl),
DECL_ATTRIBUTES (newdecl));
}
/* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current /* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current
function should use the MIPS16 ISA and switch modes accordingly. */ function should use the MIPS16 ISA and switch modes accordingly. */
static void static void
mips_set_current_function (tree fndecl ATTRIBUTE_UNUSED) mips_set_current_function (tree fndecl)
{ {
mips_set_mips16_mode (mips_use_mips16_mode_p (fndecl));
} }
/* Implement TARGET_HANDLE_OPTION. */ /* Implement TARGET_HANDLE_OPTION. */
...@@ -8783,7 +8934,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, ...@@ -8783,7 +8934,7 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
allowed, otherwise load the address into a register first. */ allowed, otherwise load the address into a register first. */
fnaddr = XEXP (DECL_RTL (function), 0); fnaddr = XEXP (DECL_RTL (function), 0);
if (TARGET_MIPS16 || TARGET_USE_GOT || SYMBOL_REF_LONG_CALL_P (fnaddr) if (TARGET_MIPS16 || TARGET_USE_GOT || SYMBOL_REF_LONG_CALL_P (fnaddr)
|| SYMBOL_REF_MIPS16_FUNC_P (fnaddr)) || mips_use_mips16_mode_p (function))
{ {
/* This is messy. gas treats "la $25,foo" as part of a call /* This is messy. gas treats "la $25,foo" as part of a call
sequence and may allow a global "foo" to be lazily bound. sequence and may allow a global "foo" to be lazily bound.
...@@ -12724,43 +12875,6 @@ mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target) ...@@ -12724,43 +12875,6 @@ mips_expand_builtin_bposge (enum mips_builtin_type builtin_type, rtx target)
const1_rtx, const0_rtx); const1_rtx, const0_rtx);
} }
/* Return true if we should force MIPS16 mode for the function named by
the SYMBOL_REF SYMBOL, which belongs to DECL and has type TYPE.
FIRST is true if this is the first time handling this decl. */
static bool
mips_use_mips16_mode_p (rtx symbol, tree decl, int first, tree type)
{
tree parent;
/* Explicit function attributes take precedence. */
if (mips_mips16_type_p (type))
return true;
if (mips_nomips16_type_p (type))
return false;
/* A nested function should inherit the MIPS16 setting from its parent. */
parent = decl_function_context (decl);
if (parent)
return SYMBOL_REF_MIPS16_FUNC_P (XEXP (DECL_RTL (parent), 0));
/* Handle -mflip-mips16. */
if (TARGET_FLIP_MIPS16
&& !DECL_BUILT_IN (decl)
&& !DECL_ARTIFICIAL (decl))
{
if (!first)
/* Use the setting we picked first time around. */
return SYMBOL_REF_MIPS16_FUNC_P (symbol);
mips16_flipper = !mips16_flipper;
if (mips16_flipper)
return !mips_base_mips16;
}
return mips_base_mips16;
}
/* Set SYMBOL_REF_FLAGS for the SYMBOL_REF inside RTL, which belongs to DECL. /* Set SYMBOL_REF_FLAGS for the SYMBOL_REF inside RTL, which belongs to DECL.
FIRST is true if this is the first time handling this decl. */ FIRST is true if this is the first time handling this decl. */
...@@ -12777,14 +12891,6 @@ mips_encode_section_info (tree decl, rtx rtl, int first) ...@@ -12777,14 +12891,6 @@ mips_encode_section_info (tree decl, rtx rtl, int first)
if ((TARGET_LONG_CALLS && !mips_near_type_p (type)) if ((TARGET_LONG_CALLS && !mips_near_type_p (type))
|| mips_far_type_p (type)) || mips_far_type_p (type))
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL; SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_LONG_CALL;
if (mips_use_mips16_mode_p (symbol, decl, first, type))
{
if (flag_pic || TARGET_ABICALLS)
sorry ("MIPS16 PIC");
else
SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_MIPS16_FUNC;
}
} }
} }
......
...@@ -2338,11 +2338,6 @@ typedef struct mips_args { ...@@ -2338,11 +2338,6 @@ typedef struct mips_args {
#define SYMBOL_REF_LONG_CALL_P(X) \ #define SYMBOL_REF_LONG_CALL_P(X) \
((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0) ((SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_LONG_CALL) != 0)
/* Flag to mark a function decl symbol a "mips16" function. */
#define SYMBOL_FLAG_MIPS16_FUNC (SYMBOL_FLAG_MACH_DEP << 1)
#define SYMBOL_REF_MIPS16_FUNC_P(RTX) \
((SYMBOL_REF_FLAGS (RTX) & SYMBOL_FLAG_MIPS16_FUNC) != 0)
/* True if we're generating a form of MIPS16 code in which jump tables /* True if we're generating a form of MIPS16 code in which jump tables
are stored in the text section and encoded as 16-bit PC-relative are stored in the text section and encoded as 16-bit PC-relative
offsets. This is only possible when general text loads are allowed, offsets. This is only possible when general text loads are allowed,
......
2007-09-13 Richard Sandiford <richard@codesourcery.com>
* gcc.dg/gcc-have-sync-compare-and-swap.c: Skip for -mflip-mips16.
* gcc.target/mips/mips16-attributes-2.c: New test.
* gcc.target/mips/mips16-attributes-3.c: Likewise.
* gcc.target/mips/args-3.c: Skip for -mflip-mips16. Do not use the
hard-float asm when __mips16 is defined.
* gcc.target/mips/atomic-memory-1.c (main): Add a nomips16 attribute.
* gcc.target/mips/atomic-memory-2.c (main): Likewise.
* gcc.target/mips/fpcmp-1.c (f1, f2): Likewise.
* gcc.target/mips/fpcmp-2.c (f1, f2): Likewise.
* gcc.target/mips/neg-abs-1.c (f1, f2, d1, f2): Likewise.
* gcc.target/mips/pr26765.c (foo): Likewise.
* gcc.target/mips/gcc-have-sync-compare-and-swap-1.c: Run for all
targets, use dg-mips-options instead of dg-options, and use -mgp32
to force 32-bit mode.
* gcc.target/mips/gcc-have-sync-compare-and-swap-2.c: Likewise -mgp64
and 64-bit mode.
* gcc.target/mips/mips.exp (is_gp32_flag): Return true for -mips32*.
2007-09-12 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com> 2007-09-12 Dwarakanath Rajagopal <dwarak.rajagopal@amd.com>
Michael Meissner <michael.meissner@amd.com> Michael Meissner <michael.meissner@amd.com>
/* { dg-do link } */ /* { dg-do link } */
/* MIPS only supports these built-in functions for non-MIPS16 mode, and
-mflip-mips16 will change the mode of some functions to be different
from the command-line setting. */
/* { dg-skip-if "" { mips*-*-* } { "-mflip-mips16" } { "" } } */
void f1() void f1()
{ {
......
/* __mips, and related defines, guarantee that certain assembly /* __mips, and related defines, guarantee that certain assembly
instructions can be used. Check a few examples. */ instructions can be used. Check a few examples. */
/* { dg-do run } */ /* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "-mflip-mips16" } { "" } } */
extern void abort (void); extern void abort (void);
extern void exit (int); extern void exit (int);
...@@ -11,7 +12,7 @@ int foo (float inf, int64 in64, int32 in32) ...@@ -11,7 +12,7 @@ int foo (float inf, int64 in64, int32 in32)
int64 res64; int64 res64;
int32 res32; int32 res32;
#if __mips != 1 && defined (__mips_hard_float) #if __mips != 1 && defined (__mips_hard_float) && !defined (__mips16)
__asm__ ("trunc.w.s %0, %1" : "=f" (res32) : "f" (inf)); __asm__ ("trunc.w.s %0, %1" : "=f" (res32) : "f" (inf));
if (res32 != 11) if (res32 != 11)
abort (); abort ();
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
extern void abort (void); extern void abort (void);
extern void exit (int); extern void exit (int);
int main () #define NOMIPS16 __attribute__ ((nomips16))
NOMIPS16 int main ()
{ {
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
unsigned v = 0; unsigned v = 0;
......
...@@ -3,7 +3,9 @@ ...@@ -3,7 +3,9 @@
/* { dg-final { scan-assembler "addiu" } } */ /* { dg-final { scan-assembler "addiu" } } */
/* { dg-final { scan-assembler-not "subu" } } */ /* { dg-final { scan-assembler-not "subu" } } */
unsigned long #define NOMIPS16 __attribute__ ((nomips16))
NOMIPS16 unsigned long
f(unsigned long *p) f(unsigned long *p)
{ {
return __sync_fetch_and_sub (p, 5); return __sync_fetch_and_sub (p, 5);
......
/* We used to use c.lt.fmt instead of c.ule.fmt here. */ /* We used to use c.lt.fmt instead of c.ule.fmt here. */
/* { dg-mips-options "-mhard-float -O2" } */ /* { dg-mips-options "-mhard-float -O2" } */
int f1 (float x, float y) { return __builtin_isless (x, y); } #define NOMIPS16 __attribute__ ((nomips16))
int f2 (double x, double y) { return __builtin_isless (x, y); }
NOMIPS16 int f1 (float x, float y) { return __builtin_isless (x, y); }
NOMIPS16 int f2 (double x, double y) { return __builtin_isless (x, y); }
/* { dg-final { scan-assembler "c\\.ule\\.s" } } */ /* { dg-final { scan-assembler "c\\.ule\\.s" } } */
/* { dg-final { scan-assembler "c\\.ule\\.d" } } */ /* { dg-final { scan-assembler "c\\.ule\\.d" } } */
/* We used to use c.le.fmt instead of c.ult.fmt here. */ /* We used to use c.le.fmt instead of c.ult.fmt here. */
/* { dg-mips-options "-mhard-float -O2" } */ /* { dg-mips-options "-mhard-float -O2" } */
int f1 (float x, float y) { return __builtin_islessequal (x, y); } #define NOMIPS16 __attribute__ ((nomips16))
int f2 (double x, double y) { return __builtin_islessequal (x, y); }
NOMIPS16 int f1 (float x, float y) { return __builtin_islessequal (x, y); }
NOMIPS16 int f2 (double x, double y) { return __builtin_islessequal (x, y); }
/* { dg-final { scan-assembler "c\\.ult\\.s" } } */ /* { dg-final { scan-assembler "c\\.ult\\.s" } } */
/* { dg-final { scan-assembler "c\\.ult\\.d" } } */ /* { dg-final { scan-assembler "c\\.ult\\.d" } } */
/* { dg-do preprocess } */ /* { dg-do preprocess } */
/* { dg-options "-mips32 -mabi=32" } */ /* { dg-mips-options "-mips2" } */
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono #error nonono
......
/* { dg-do preprocess { target { mips64*-*-* } } } */ /* { dg-do preprocess } */
/* { dg-options "-mips64 -mabi=64" } */ /* { dg-mips-options "-mgp64" } */
#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1
#error nonono #error nonono
......
...@@ -103,6 +103,7 @@ proc is_gp32_flag {flag} { ...@@ -103,6 +103,7 @@ proc is_gp32_flag {flag} {
switch -glob -- $flag { switch -glob -- $flag {
-msmartmips - -msmartmips -
-mips[12] - -mips[12] -
-mips32* -
-march=mips32* - -march=mips32* -
-mgp32 { return 1 } -mgp32 { return 1 }
default { return 0 } default { return 0 }
......
/* { dg-skip-if "" { *-*-* } { "-mflip-mips16" } { "" } } */
void f1 (void);
void __attribute__((mips16)) f1 (void) {} /* { dg-error "conflicting" } */
void __attribute__((mips16)) f2 (void);
void f2 (void) {} /* { dg-error "conflicting" } */
void f3 (void);
void __attribute__((nomips16)) f3 (void) {} /* { dg-error "conflicting" } */
void __attribute__((nomips16)) f4 (void);
void f4 (void) {} /* { dg-error "conflicting" } */
void __attribute__((mips16, nomips16)) f5 (void) {} /* { dg-error "cannot have both" } */
/* We should be able to assign mips16 and nomips16 functions to a pointer. */
void __attribute__((mips16)) f1 (void);
void (*ptr1) (void) = f1;
void __attribute__((nomips16)) f2 (void);
void (*ptr2) (void) = f2;
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
/* { dg-final { scan-assembler "abs.s" } } */ /* { dg-final { scan-assembler "abs.s" } } */
/* { dg-final { scan-assembler "abs.d" } } */ /* { dg-final { scan-assembler "abs.d" } } */
float f1 (float f) { return -f; } #define NOMIPS16 __attribute__ ((nomips16))
float f2 (float f) { return __builtin_fabsf (f); }
double d1 (double d) { return -d; } NOMIPS16 float f1 (float f) { return -f; }
double d2 (double d) { return __builtin_fabs (d); } NOMIPS16 float f2 (float f) { return __builtin_fabsf (f); }
NOMIPS16 double d1 (double d) { return -d; }
NOMIPS16 double d2 (double d) { return __builtin_fabs (d); }
...@@ -6,7 +6,9 @@ ...@@ -6,7 +6,9 @@
__thread int *a = 0; __thread int *a = 0;
void foo (void) #define NOMIPS16 __attribute__ ((nomips16))
NOMIPS16 void foo (void)
{ {
extern int *b; extern int *b;
b = (int *) ((*a)); b = (int *) ((*a));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment