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.

From-SVN: r100418
This commit is contained in:
Geoffrey Keating 2005-06-01 00:45:24 +00:00
parent f991abd12d
commit a9c9d3fa23
5 changed files with 151 additions and 3 deletions

View File

@ -1,3 +1,11 @@
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.
2005-05-30 Daniel Berlin <dberlin@dberlin.org>
* c-objc-common.c (c_tree_printer): Check flag before hashtable.

View File

@ -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);

View File

@ -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"

View File

@ -1,3 +1,9 @@
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.
2005-05-31 Zdenek Dvorak <dvorakz@suse.cz>
PR tree-optimization/21817
@ -83,6 +89,9 @@
2005-05-29 Geoffrey Keating <geoffk@apple.com>
PR c++/17413
* g++.dg/template/local5.C: New.
PR target/21761
* gcc.c-torture/compile/pr21761.c: New.

View File

@ -0,0 +1,99 @@
/* { dg-do run } */
/* { dg-require-effective-target sync_char_short } */
/* Test functionality of the intrinsics for 'short' and 'char'. */
extern void abort (void);
extern void *memcpy (void *, const void *, __SIZE_TYPE__);
static char AI[18];
static char init_qi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 };
static char test_qi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 };
static void
do_qi (void)
{
if (__sync_fetch_and_add(AI+4, 1) != 0)
abort ();
if (__sync_fetch_and_add(AI+5, 4) != 0)
abort ();
if (__sync_fetch_and_add(AI+6, 22) != 0)
abort ();
if (__sync_fetch_and_sub(AI+7, 12) != 0)
abort ();
if (__sync_fetch_and_and(AI+8, 7) != -1)
abort ();
if (__sync_fetch_and_or(AI+9, 8) != 0)
abort ();
if (__sync_fetch_and_xor(AI+10, 9) != 0)
abort ();
if (__sync_fetch_and_nand(AI+11, 7) != 0)
abort ();
if (__sync_add_and_fetch(AI+12, 1) != 1)
abort ();
if (__sync_sub_and_fetch(AI+13, 12) != -12)
abort ();
if (__sync_and_and_fetch(AI+14, 7) != 7)
abort ();
if (__sync_or_and_fetch(AI+15, 8) != 8)
abort ();
if (__sync_xor_and_fetch(AI+16, 9) != 9)
abort ();
if (__sync_nand_and_fetch(AI+17, 7) != 7)
abort ();
}
static short AL[18];
static short init_hi[18] = { 3,5,7,9,0,0,0,0,-1,0,0,0,0,0,-1,0,0,0 };
static short test_hi[18] = { 3,5,7,9,1,4,22,-12,7,8,9,7,1,-12,7,8,9,7 };
static void
do_hi (void)
{
if (__sync_fetch_and_add(AL+4, 1) != 0)
abort ();
if (__sync_fetch_and_add(AL+5, 4) != 0)
abort ();
if (__sync_fetch_and_add(AL+6, 22) != 0)
abort ();
if (__sync_fetch_and_sub(AL+7, 12) != 0)
abort ();
if (__sync_fetch_and_and(AL+8, 7) != -1)
abort ();
if (__sync_fetch_and_or(AL+9, 8) != 0)
abort ();
if (__sync_fetch_and_xor(AL+10, 9) != 0)
abort ();
if (__sync_fetch_and_nand(AL+11, 7) != 0)
abort ();
if (__sync_add_and_fetch(AL+12, 1) != 1)
abort ();
if (__sync_sub_and_fetch(AL+13, 12) != -12)
abort ();
if (__sync_and_and_fetch(AL+14, 7) != 7)
abort ();
if (__sync_or_and_fetch(AL+15, 8) != 8)
abort ();
if (__sync_xor_and_fetch(AL+16, 9) != 9)
abort ();
if (__sync_nand_and_fetch(AL+17, 7) != 7)
abort ();
}
int main()
{
memcpy(AI, init_qi, sizeof(init_qi));
memcpy(AL, init_hi, sizeof(init_hi));
do_qi ();
do_hi ();
if (memcmp (AI, test_qi, sizeof(test_qi)))
abort ();
if (memcmp (AL, test_hi, sizeof(test_hi)))
abort ();
return 0;
}