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:
parent
f991abd12d
commit
a9c9d3fa23
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
|
||||
|
99
gcc/testsuite/gcc.dg/sync-2.c
Normal file
99
gcc/testsuite/gcc.dg/sync-2.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user