aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid Daney <ddaney@avtrex.com>2008-05-08 17:04:12 +0000
committerDavid Daney <daney@gcc.gnu.org>2008-05-08 17:04:12 +0000
commit977502ff8431f42bc84b71dd5814658439610c7b (patch)
tree53a03c6f31da3208a923be513b8bab95fd23f140 /gcc
parent627ab8616cc19a4bed7ca2d4273e3dc85aab39b4 (diff)
downloadgcc-977502ff8431f42bc84b71dd5814658439610c7b.zip
gcc-977502ff8431f42bc84b71dd5814658439610c7b.tar.gz
gcc-977502ff8431f42bc84b71dd5814658439610c7b.tar.bz2
target-supports.exp (check_effective_target_sync_int_long): Add mips*-*-*.
2008-05-08 David Daney <ddaney@avtrex.com> * lib/target-supports.exp (check_effective_target_sync_int_long): Add mips*-*-*. (check_effective_target_sync_char_short): Same. 2008-05-08 David Daney <ddaney@avtrex.com> Richard Sandiford <rsandifo@nildram.co.uk> * config/mips/mips.md (mips_expand_compare_and_swap_12): Handle special case of constant zero operands. * config/mips/mips.c (mips_expand_compare_and_swap_12): Zero extend old and new values. Special case constant zero values. * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Skip 'sync' if compare fails. (MIPS_COMPARE_AND_SWAP_12): Handle constant zero operands. (MIPS_COMPARE_AND_SWAP_12_0): New macro. Co-Authored-By: Richard Sandiford <rsandifo@nildram.co.uk> From-SVN: r135088
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/mips/mips.c32
-rw-r--r--gcc/config/mips/mips.h19
-rw-r--r--gcc/config/mips/mips.md19
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/lib/target-supports.exp6
6 files changed, 71 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7ac7cd2..ae8d7a9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2008-05-08 David Daney <ddaney@avtrex.com>
+ Richard Sandiford <rsandifo@nildram.co.uk>
+
+ * config/mips/mips.md (mips_expand_compare_and_swap_12): Handle
+ special case of constant zero operands.
+ * config/mips/mips.c (mips_expand_compare_and_swap_12): Zero extend
+ old and new values. Special case constant zero values.
+ * config/mips/mips.h (MIPS_COMPARE_AND_SWAP): Skip 'sync' if compare
+ fails.
+ (MIPS_COMPARE_AND_SWAP_12): Handle constant zero operands.
+ (MIPS_COMPARE_AND_SWAP_12_0): New macro.
+
2008-05-08 Paolo Bonzini <bonzini@gnu.org>
PR target/36090
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index de2e42a..2189533 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -5880,7 +5880,10 @@ void
mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
{
rtx orig_addr, memsi_addr, memsi, shift, shiftsi, unshifted_mask;
- rtx mask, inverted_mask, oldvalsi, old_shifted, newvalsi, new_shifted, res;
+ rtx unshifted_mask_reg, mask, inverted_mask, res;
+ enum machine_mode mode;
+
+ mode = GET_MODE (mem);
/* Compute the address of the containing SImode value. */
orig_addr = force_reg (Pmode, XEXP (mem, 0));
@@ -5896,8 +5899,7 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
counting from the least significant byte. */
shift = mips_force_binary (Pmode, AND, orig_addr, GEN_INT (3));
if (TARGET_BIG_ENDIAN)
- mips_emit_binary (XOR, shift, shift,
- GEN_INT (GET_MODE (mem) == QImode ? 3 : 2));
+ mips_emit_binary (XOR, shift, shift, GEN_INT (mode == QImode ? 3 : 2));
/* Multiply by eight to convert the shift value from bytes to bits. */
mips_emit_binary (ASHIFT, shift, shift, GEN_INT (3));
@@ -5907,9 +5909,9 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
shiftsi = force_reg (SImode, gen_lowpart (SImode, shift));
/* Set MASK to an inclusive mask of the QImode or HImode value. */
- unshifted_mask = GEN_INT (GET_MODE_MASK (GET_MODE (mem)));
- unshifted_mask = force_reg (SImode, unshifted_mask);
- mask = mips_force_binary (SImode, ASHIFT, unshifted_mask, shiftsi);
+ unshifted_mask = GEN_INT (GET_MODE_MASK (mode));
+ unshifted_mask_reg = force_reg (SImode, unshifted_mask);
+ mask = mips_force_binary (SImode, ASHIFT, unshifted_mask_reg, shiftsi);
/* Compute the equivalent exclusive mask. */
inverted_mask = gen_reg_rtx (SImode);
@@ -5917,17 +5919,25 @@ mips_expand_compare_and_swap_12 (rtx result, rtx mem, rtx oldval, rtx newval)
gen_rtx_NOT (SImode, mask)));
/* Shift the old value into place. */
- oldvalsi = force_reg (SImode, gen_lowpart (SImode, oldval));
- old_shifted = mips_force_binary (SImode, ASHIFT, oldvalsi, shiftsi);
+ if (oldval != const0_rtx)
+ {
+ oldval = convert_modes (SImode, mode, oldval, true);
+ oldval = force_reg (SImode, oldval);
+ oldval = mips_force_binary (SImode, ASHIFT, oldval, shiftsi);
+ }
/* Do the same for the new value. */
- newvalsi = force_reg (SImode, gen_lowpart (SImode, newval));
- new_shifted = mips_force_binary (SImode, ASHIFT, newvalsi, shiftsi);
+ if (newval != const0_rtx)
+ {
+ newval = convert_modes (SImode, mode, newval, true);
+ newval = force_reg (SImode, newval);
+ newval = mips_force_binary (SImode, ASHIFT, newval, shiftsi);
+ }
/* Do the SImode atomic access. */
res = gen_reg_rtx (SImode);
emit_insn (gen_compare_and_swap_12 (res, memsi, mask, inverted_mask,
- old_shifted, new_shifted));
+ oldval, newval));
/* Shift and convert the result. */
mips_emit_binary (AND, res, res, mask);
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 1391c99..9f59f1a 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -2902,7 +2902,8 @@ while (0)
"\tsc" SUFFIX "\t%@,%1\n" \
"\tbeq\t%@,%.,1b\n" \
"\tnop\n" \
- "2:\tsync%-%]%>%)"
+ "\tsync%-%]%>%)\n" \
+ "2:\n"
/* Return an asm string that atomically:
@@ -2919,7 +2920,7 @@ while (0)
"%(%<%[%|sync\n" \
"1:\tll\t%0,%1\n" \
"\tand\t%@,%0,%2\n" \
- "\tbne\t%@,%4,2f\n" \
+ "\tbne\t%@,%z4,2f\n" \
"\tand\t%@,%0,%3\n" \
"\tor\t%@,%@,%5\n" \
"\tsc\t%@,%1\n" \
@@ -2928,6 +2929,20 @@ while (0)
"\tsync%-%]%>%)\n" \
"2:\n"
+/* Like MIPS_COMPARE_AND_SWAP_12, except %5 is a constant zero,
+ so the OR can be omitted. */
+#define MIPS_COMPARE_AND_SWAP_12_0 \
+ "%(%<%[%|sync\n" \
+ "1:\tll\t%0,%1\n" \
+ "\tand\t%@,%0,%2\n" \
+ "\tbne\t%@,%z4,2f\n" \
+ "\tand\t%@,%0,%3\n" \
+ "\tsc\t%@,%1\n" \
+ "\tbeq\t%@,%.,1b\n" \
+ "\tnop\n" \
+ "\tsync%-%]%>%)\n" \
+ "2:\n"
+
/* Return an asm string that atomically:
- Sets memory reference %0 to %0 INSN %1.
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 05adf22..a423529 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -4462,19 +4462,22 @@
;; Helper insn for mips_expand_compare_and_swap_12.
(define_insn "compare_and_swap_12"
- [(set (match_operand:SI 0 "register_operand" "=&d")
- (match_operand:SI 1 "memory_operand" "+R"))
+ [(set (match_operand:SI 0 "register_operand" "=&d,&d")
+ (match_operand:SI 1 "memory_operand" "+R,R"))
(set (match_dup 1)
- (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d")
- (match_operand:SI 3 "register_operand" "d")
- (match_operand:SI 4 "register_operand" "d")
- (match_operand:SI 5 "register_operand" "d")]
+ (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "d,d")
+ (match_operand:SI 3 "register_operand" "d,d")
+ (match_operand:SI 4 "reg_or_0_operand" "dJ,dJ")
+ (match_operand:SI 5 "reg_or_0_operand" "d,J")]
UNSPEC_COMPARE_AND_SWAP_12))]
"GENERATE_LL_SC"
{
- return MIPS_COMPARE_AND_SWAP_12;
+ if (which_alternative == 0)
+ return MIPS_COMPARE_AND_SWAP_12;
+ else
+ return MIPS_COMPARE_AND_SWAP_12_0;
}
- [(set_attr "length" "40")])
+ [(set_attr "length" "40,36")])
(define_insn "sync_add<mode>"
[(set (match_operand:GPR 0 "memory_operand" "+R,R")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3106bfb..ff5d2cc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2008-05-08 David Daney <ddaney@avtrex.com>
+
+ * lib/target-supports.exp (check_effective_target_sync_int_long): Add
+ mips*-*-*.
+ (check_effective_target_sync_char_short): Same.
+
2008-05-08 Kai Tietz <kai.tietz@onevision.com>
* gcc.c-torture/compile/pr36172.c: Replace unsigned long by
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index de78c71..150a217 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -2052,7 +2052,8 @@ proc check_effective_target_sync_int_long { } {
|| [istarget s390*-*-*]
|| [istarget powerpc*-*-*]
|| [istarget sparc64-*-*]
- || [istarget sparcv9-*-*] } {
+ || [istarget sparcv9-*-*]
+ || [istarget mips*-*-*] } {
set et_sync_int_long_saved 1
}
}
@@ -2079,7 +2080,8 @@ proc check_effective_target_sync_char_short { } {
|| [istarget s390*-*-*]
|| [istarget powerpc*-*-*]
|| [istarget sparc64-*-*]
- || [istarget sparcv9-*-*] } {
+ || [istarget sparcv9-*-*]
+ || [istarget mips*-*-*] } {
set et_sync_char_short_saved 1
}
}