aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/mips
diff options
context:
space:
mode:
authorDavid Daney <ddaney@avtrex.com>2007-09-11 20:14:51 +0000
committerDavid Daney <daney@gcc.gnu.org>2007-09-11 20:14:51 +0000
commit66471b4708b84db82570b9747fb4e157c23f9804 (patch)
tree14dfcb7d16ebfd463a4f9ecab96e3573379f51d0 /gcc/config/mips
parentfa89b6ecba4ce9448b82a21f91b360eacf57bc72 (diff)
downloadgcc-66471b4708b84db82570b9747fb4e157c23f9804.zip
gcc-66471b4708b84db82570b9747fb4e157c23f9804.tar.gz
gcc-66471b4708b84db82570b9747fb4e157c23f9804.tar.bz2
invoke.texi: Document new MIPS -mllsc and -mno-llsc options.
* doc/invoke.texi: Document new MIPS -mllsc and -mno-llsc options. * doc/install.texi: Document new --with-llsc and --without-llsc options. * config.gcc: Handle --with-llsc and --without-llsc configure options. * config/mips/mips.md (sync, memory_barrier): Wrap sync instrunction in %| and %- operand codes. Depend on GENERATE_SYNC instead of ISA_HAS_SYNC. (sync_compare_and_swap<mode>, sync_add<mode>, sync_sub<mode>, sync_old_add<mode>, sync_old_sub<mode>, sync_new_add<mode>, sync_new_sub<mode>, sync_<optab><mode>, sync_old_<optab><mode>, sync_new_<optab><mode>, sync_nand<mode>, sync_old_nand<mode>, sync_new_nand<mode>, sync_lock_test_and_set<mode>): Depend on GENERATE_LL_SC instead of ISA_HAS_LL_SC. * config/mips/mips.opt (mllsc): New option. * config/mips/mips.c (mips_llsc): Define variable. (mips_handle_option): Handle mllsc option. (override_options): Set mips_print_operand_punct for '|' and '-'. (print_operand): Add new %| and %- operand codes. * config/mips/mips.h (mips_llsc_setting): New enum type. (mips_llsc): Declare. (OPTION_DEFAULT_SPECS): Add llsc handling. (GENERATE_SYNC): New macro. (GENERATE_LL_SC): New macro. (MIPS_COMPARE_AND_SWAP, MIPS_SYNC_OP, MIPS_SYNC_OLD_OP, MIPS_SYNC_NEW_OP, MIPS_SYNC_NAND, MIPS_SYNC_OLD_NAND, MIPS_SYNC_NEW_NAND, MIPS_SYNC_EXCHANGE): Wrap instructions in %| and %- operand codes. From-SVN: r128392
Diffstat (limited to 'gcc/config/mips')
-rw-r--r--gcc/config/mips/mips.c26
-rw-r--r--gcc/config/mips/mips.h55
-rw-r--r--gcc/config/mips/mips.md36
-rw-r--r--gcc/config/mips/mips.opt4
4 files changed, 84 insertions, 37 deletions
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 289f46e..1a2cc06 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -636,6 +636,9 @@ static GTY(()) int mips16_flipper;
/* The -mtext-loads setting. */
enum mips_code_readable_setting mips_code_readable = CODE_READABLE_YES;
+/* The -mllsc setting. */
+enum mips_llsc_setting mips_llsc = LLSC_DEFAULT;
+
/* The architecture selected by -mipsN. */
static const struct mips_cpu_info *mips_isa_info;
@@ -5711,7 +5714,7 @@ mips_set_current_function (tree fndecl ATTRIBUTE_UNUSED)
/* Implement TARGET_HANDLE_OPTION. */
static bool
-mips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
+mips_handle_option (size_t code, const char *arg, int value)
{
switch (code)
{
@@ -5753,6 +5756,10 @@ mips_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
return false;
return true;
+ case OPT_mllsc:
+ mips_llsc = value ? LLSC_YES : LLSC_NO;
+ return true;
+
default:
return true;
}
@@ -6015,6 +6022,8 @@ override_options (void)
mips_print_operand_punct['$'] = 1;
mips_print_operand_punct['+'] = 1;
mips_print_operand_punct['~'] = 1;
+ mips_print_operand_punct['|'] = 1;
+ mips_print_operand_punct['-'] = 1;
/* Set up array to map GCC register number to debug register number.
Ignore the special purpose register numbers. */
@@ -6377,7 +6386,10 @@ mips_strip_unspec_address (rtx op)
'^' Print the name of the pic call-through register (t9 or $25).
'$' Print the name of the stack pointer register (sp or $29).
'+' Print the name of the gp register (usually gp or $28).
- '~' Output a branch alignment to LABEL_ALIGN(NULL). */
+ '~' Output a branch alignment to LABEL_ALIGN(NULL).
+ '|' Print .set push; .set mips2 if mips_llsc == LLSC_YES
+ && !ISA_HAS_LL_SC.
+ '-' Print .set pop under the same conditions for '|'. */
void
print_operand (FILE *file, rtx op, int letter)
@@ -6507,6 +6519,16 @@ print_operand (FILE *file, rtx op, int letter)
}
break;
+ case '|':
+ if (!ISA_HAS_LL_SC)
+ fputs (".set\tpush\n\t.set\tmips2\n\t", file);
+ break;
+
+ case '-':
+ if (!ISA_HAS_LL_SC)
+ fputs ("\n\t.set\tpop", file);
+ break;
+
default:
error ("PRINT_OPERAND: unknown punctuation '%c'", letter);
break;
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index ca534bf..7aa6aa8 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -121,6 +121,14 @@ enum mips_code_readable_setting {
CODE_READABLE_YES
};
+
+/* Enumerates the setting of the -mllsc option. */
+enum mips_llsc_setting {
+ LLSC_DEFAULT,
+ LLSC_NO,
+ LLSC_YES
+};
+
#ifndef USED_FOR_TARGET
extern char mips_print_operand_punct[256]; /* print_operand punctuation chars */
extern const char *current_function_file; /* filename current function is in */
@@ -145,6 +153,7 @@ extern const struct mips_cpu_info *mips_arch_info;
extern const struct mips_cpu_info *mips_tune_info;
extern const struct mips_rtx_cost_data *mips_cost;
extern enum mips_code_readable_setting mips_code_readable;
+extern enum mips_llsc_setting mips_llsc;
#endif
/* Macros to silence warnings about numbers being signed in traditional
@@ -688,7 +697,8 @@ extern enum mips_code_readable_setting mips_code_readable;
{"tune", "%{!mtune=*:-mtune=%(VALUE)}" }, \
{"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
- {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }
+ {"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
+ {"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }
#define GENERATE_DIVIDE_TRAPS (TARGET_DIVIDE_TRAPS \
@@ -893,11 +903,15 @@ extern enum mips_code_readable_setting mips_code_readable;
/* ISA includes sync. */
#define ISA_HAS_SYNC ((mips_isa >= 2 || TARGET_MIPS3900) && !TARGET_MIPS16)
+#define GENERATE_SYNC (mips_llsc == LLSC_YES \
+ || (mips_llsc == LLSC_DEFAULT && ISA_HAS_SYNC))
/* ISA includes ll and sc. Note that this implies ISA_HAS_SYNC
because the expanders use both ISA_HAS_SYNC and ISA_HAS_LL_SC
instructions. */
#define ISA_HAS_LL_SC (mips_isa >= 2 && !TARGET_MIPS16)
+#define GENERATE_LL_SC (mips_llsc == LLSC_YES \
+ || (mips_llsc == LLSC_DEFAULT && ISA_HAS_LL_SC))
/* Add -G xx support. */
@@ -2913,11 +2927,12 @@ while (0)
and OP is the instruction that should be used to load %3 into a
register. */
#define MIPS_COMPARE_AND_SWAP(SUFFIX, OP) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tbne\t%0,%2,2f\n" \
"\t" OP "\t%@,%3\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
+ "\tsc" SUFFIX "\t%@,%1" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop\n" \
"2:%]%>%)"
@@ -2929,10 +2944,11 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%@,%0\n" \
"\t" INSN "\t%@,%@,%1\n" \
- "\tsc" SUFFIX "\t%@,%0\n" \
+ "\tsc" SUFFIX "\t%@,%0" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop%]%>%)"
@@ -2945,10 +2961,11 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_OLD_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
+ "\tsc" SUFFIX "\t%@,%1" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop%]%>%)"
@@ -2961,10 +2978,11 @@ while (0)
SUFFIX is the suffix that should be added to "ll" and "sc"
instructions. */
#define MIPS_SYNC_NEW_OP(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
+ "\tsc" SUFFIX "\t%@,%1" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\t" INSN "\t%0,%0,%2%]%>%)"
@@ -2976,11 +2994,12 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%@,%0\n" \
"\tnor\t%@,%@,%.\n" \
"\t" INSN "\t%@,%@,%1\n" \
- "\tsc" SUFFIX "\t%@,%0\n" \
+ "\tsc" SUFFIX "\t%@,%0" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop%]%>%)"
@@ -2994,11 +3013,12 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_OLD_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tnor\t%@,%0,%.\n" \
"\t" INSN "\t%@,%@,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
+ "\tsc" SUFFIX "\t%@,%1" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop%]%>%)"
@@ -3012,11 +3032,12 @@ while (0)
instructions. INSN is the and instruction needed to and a register
with %2. */
#define MIPS_SYNC_NEW_NAND(SUFFIX, INSN) \
- "%(%<%[sync\n" \
+ "%(%<%[%|sync\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\tnor\t%0,%0,%.\n" \
"\t" INSN "\t%@,%0,%2\n" \
- "\tsc" SUFFIX "\t%@,%1\n" \
+ "\tsc" SUFFIX "\t%@,%1" \
+ "%-\n" \
"\tbeq\t%@,%.,1b\n" \
"\t" INSN "\t%0,%0,%2%]%>%)"
@@ -3030,11 +3051,11 @@ while (0)
instructions. OP is the and instruction that should be used to
load %2 into a register. */
#define MIPS_SYNC_EXCHANGE(SUFFIX, OP) \
- "%(%<%[\n" \
+ "%(%<%[%|\n" \
"1:\tll" SUFFIX "\t%0,%1\n" \
"\t" OP "\t%@,%2\n" \
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop\n" \
- "\tsync%]%>%)"
+ "\tsync%-%]%>%)"
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index c1cffb1..2999806 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4285,8 +4285,8 @@
(define_insn "sync"
[(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
- "ISA_HAS_SYNC"
- "sync")
+ "GENERATE_SYNC"
+ "%|sync%-")
(define_insn "synci"
[(unspec_volatile [(match_operand 0 "pmode_register_operand" "d")]
@@ -4323,8 +4323,8 @@
(define_insn "memory_barrier"
[(set (mem:BLK (scratch))
(unspec:BLK [(const_int 0)] UNSPEC_MEMORY_BARRIER))]
- "ISA_HAS_SYNC"
- "sync")
+ "GENERATE_SYNC"
+ "%|sync%-")
(define_insn "sync_compare_and_swap<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&d,d")
@@ -4333,7 +4333,7 @@
(unspec_volatile:GPR [(match_operand:GPR 2 "register_operand" "d,d")
(match_operand:GPR 3 "arith_operand" "I,d")]
UNSPEC_COMPARE_AND_SWAP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_COMPARE_AND_SWAP ("<d>", "li");
@@ -4348,7 +4348,7 @@
[(plus:GPR (match_dup 0)
(match_operand:GPR 1 "arith_operand" "I,d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OP ("<d>", "<d>addiu");
@@ -4363,7 +4363,7 @@
[(minus:GPR (match_dup 0)
(match_operand:GPR 1 "register_operand" "d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_OP ("<d>", "<d>subu");
}
@@ -4377,7 +4377,7 @@
[(plus:GPR (match_dup 1)
(match_operand:GPR 2 "arith_operand" "I,d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_OP ("<d>", "<d>addiu");
@@ -4394,7 +4394,7 @@
[(minus:GPR (match_dup 1)
(match_operand:GPR 2 "register_operand" "d"))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_OLD_OP ("<d>", "<d>subu");
}
@@ -4408,7 +4408,7 @@
(unspec_volatile:GPR
[(plus:GPR (match_dup 1) (match_dup 2))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_OP ("<d>", "<d>addiu");
@@ -4425,7 +4425,7 @@
(unspec_volatile:GPR
[(minus:GPR (match_dup 1) (match_dup 2))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
return MIPS_SYNC_NEW_OP ("<d>", "<d>subu");
}
@@ -4437,7 +4437,7 @@
[(fetchop_bit:GPR (match_operand:GPR 1 "uns_arith_operand" "K,d")
(match_dup 0))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OP ("<d>", "<immediate_insn>");
@@ -4454,7 +4454,7 @@
[(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
(match_dup 1))]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_OP ("<d>", "<immediate_insn>");
@@ -4471,7 +4471,7 @@
[(fetchop_bit:GPR (match_operand:GPR 2 "uns_arith_operand" "K,d")
(match_dup 1))]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_OP ("<d>", "<immediate_insn>");
@@ -4484,7 +4484,7 @@
[(set (match_operand:GPR 0 "memory_operand" "+R,R")
(unspec_volatile:GPR [(match_operand:GPR 1 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NAND ("<d>", "andi");
@@ -4499,7 +4499,7 @@
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_OLD_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_OLD_NAND ("<d>", "andi");
@@ -4514,7 +4514,7 @@
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "uns_arith_operand" "K,d")]
UNSPEC_SYNC_NEW_OP))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_NEW_NAND ("<d>", "andi");
@@ -4529,7 +4529,7 @@
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "arith_operand" "I,d")]
UNSPEC_SYNC_EXCHANGE))]
- "ISA_HAS_LL_SC"
+ "GENERATE_LL_SC"
{
if (which_alternative == 0)
return MIPS_SYNC_EXCHANGE ("<d>", "li");
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index be00ee5..bbbc305 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -176,6 +176,10 @@ mips3d
Target Report RejectNegative Mask(MIPS3D)
Use MIPS-3D instructions
+mllsc
+Target Report
+Use ll, sc and sync instructions
+
mlocal-sdata
Target Report Var(TARGET_LOCAL_SDATA) Init(1)
Use -G for object-local data