summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorgeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-01 00:45:24 +0000
committergeoffk <geoffk@138bc75d-0d04-0410-961f-82ee72b054a4>2005-06-01 00:45:24 +0000
commitb8066bf496c6a7b0cd6884f63daead536566ffad (patch)
tree03c489c612650d4829919ca9551af6bcb76c3f2b /gcc/config
parent8bc1e6ff529ff25196f82b854b7e7fe252d0d029 (diff)
downloadgcc-b8066bf496c6a7b0cd6884f63daead536566ffad.tar.gz
Index: ChangeLog
2005-05-31 Geoffrey Keating <geoffk@geoffk.org> * config/rs6000/rs6000.md (sync_boolcshort_internal): New. * config/rs6000/rs6000.c (rs6000_emit_sync): Shift count must be complemented for big-endian. Mask for AND must be rotated, not shifted. Handle short operands with NOT on the memory operation. Index: testsuite/ChangeLog 2005-05-31 Geoffrey Keating <geoffk@geoffk.org> * lib/target-supports.exp (check_effective_target_sync_char_short): New. * gcc.dg/sync-2.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@100418 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/rs6000.c21
-rw-r--r--gcc/config/rs6000/rs6000.md17
2 files changed, 35 insertions, 3 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 265a9ef402f..9f8bbd78ca8 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -11409,13 +11409,15 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
else
{
rtx addrSI, aligned_addr;
+ int shift_mask = mode == QImode ? 0x18 : 0x10;
addrSI = force_reg (SImode, gen_lowpart_common (SImode,
XEXP (used_m, 0)));
shift = gen_reg_rtx (SImode);
emit_insn (gen_rlwinm (shift, addrSI, GEN_INT (3),
- GEN_INT (0x18)));
+ GEN_INT (shift_mask)));
+ emit_insn (gen_xorsi3 (shift, shift, GEN_INT (shift_mask)));
aligned_addr = expand_binop (Pmode, and_optab,
XEXP (used_m, 0),
@@ -11453,7 +11455,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
newop = expand_binop (SImode, ior_optab,
oldop, GEN_INT (~imask), NULL_RTX,
1, OPTAB_LIB_WIDEN);
- emit_insn (gen_ashlsi3 (newop, newop, shift));
+ emit_insn (gen_rotlsi3 (newop, newop, shift));
break;
case PLUS:
@@ -11482,6 +11484,19 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
gcc_unreachable ();
}
+ if (GET_CODE (m) == NOT)
+ {
+ rtx mask, xorm;
+
+ mask = gen_reg_rtx (SImode);
+ emit_move_insn (mask, GEN_INT (imask));
+ emit_insn (gen_ashlsi3 (mask, mask, shift));
+
+ xorm = gen_rtx_XOR (SImode, used_m, mask);
+ /* Depending on the value of 'op', the XOR or the operation might
+ be able to be simplified away. */
+ newop = simplify_gen_binary (code, SImode, xorm, newop);
+ }
op = newop;
used_mode = SImode;
before = gen_reg_rtx (used_mode);
@@ -11499,7 +11514,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
after = gen_reg_rtx (used_mode);
}
- if (code == PLUS && used_mode != mode)
+ if ((code == PLUS || GET_CODE (m) == NOT) && used_mode != mode)
the_op = op; /* Computed above. */
else if (GET_CODE (op) == NOT && GET_CODE (m) != NOT)
the_op = gen_rtx_fmt_ee (code, used_mode, op, m);
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 02847df7c2f..53e4884b4b2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -14868,6 +14868,23 @@
"<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
[(set_attr "length" "16")])
+; This pattern could also take immediate values of operand 1,
+; since the non-NOT version of the operator is used; but this is not
+; very useful, since in practise operand 1 is a full 32-bit value.
+; Likewise, operand 5 is in practise either <= 2^16 or it is a register.
+(define_insn "*sync_boolcshort_internal"
+ [(set (match_operand:SI 2 "gpc_reg_operand" "=&r")
+ (match_operator:SI 4 "boolean_operator"
+ [(xor:SI (match_operand:SI 0 "memory_operand" "+Z")
+ (match_operand:SI 5 "logical_operand" "rK"))
+ (match_operand:SI 1 "gpc_reg_operand" "r")]))
+ (set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
+ (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+ (clobber (match_scratch:CC 6 "=&x"))]
+ "TARGET_POWERPC"
+ "lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16"
+ [(set_attr "length" "20")])
+
(define_insn "*sync_boolc<mode>_internal2"
[(set (match_operand:GPR 2 "gpc_reg_operand" "=&r")
(match_operator:GPR 4 "boolean_operator"