s390.c (s390_emit_compare_and_swap): New function.

2006-11-24  Andreas Krebbel  <krebbel1@de.ibm.com>

	* config/s390.c (s390_emit_compare_and_swap): New function.
	(s390_expand_cs_hqi, s390_expand_atomic): Call 
	s390_emit_compare_and_swap.

2006-11-24  Andreas Krebbel  <krebbel1@de.ibm.com>

	* gcc.dg/20061124-1.c: New testcase.

From-SVN: r119151
This commit is contained in:
Andreas Krebbel 2006-11-24 13:30:59 +00:00 committed by Andreas Krebbel
parent af1e323e93
commit 8bb501bb10
4 changed files with 51 additions and 10 deletions

View File

@ -1,3 +1,9 @@
2006-11-24 Andreas Krebbel <krebbel1@de.ibm.com>
* config/s390.c (s390_emit_compare_and_swap): New function.
(s390_expand_cs_hqi, s390_expand_atomic): Call
s390_emit_compare_and_swap.
2006-11-23 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
* pa.c (return_addr_rtx): Change 0xe0400002 to -532676606.

View File

@ -780,6 +780,24 @@ s390_emit_compare (enum rtx_code code, rtx op0, rtx op1)
return ret;
}
/* Emit a SImode compare and swap instruction setting MEM to NEW if OLD
matches CMP.
Return the correct condition RTL to be placed in the IF_THEN_ELSE of the
conditional branch testing the result. */
static rtx
s390_emit_compare_and_swap (enum rtx_code code, rtx old, rtx mem, rtx cmp, rtx new)
{
rtx ret;
emit_insn (gen_sync_compare_and_swap_ccsi (old, mem, cmp, new));
ret = gen_rtx_fmt_ee (code, VOIDmode, s390_compare_emitted, const0_rtx);
s390_compare_emitted = NULL_RTX;
return ret;
}
/* Emit a jump instruction to TARGET. If COND is NULL_RTX, emit an
unconditional jump, else a conditional jump under condition COND. */
@ -4187,11 +4205,9 @@ s390_expand_cs_hqi (enum machine_mode mode, rtx target, rtx mem, rtx cmp, rtx ne
newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new, val,
NULL_RTX, 1, OPTAB_DIRECT));
/* Emit compare_and_swap pattern. */
emit_insn (gen_sync_compare_and_swap_ccsi (res, ac.memsi, cmpv, newv));
/* Jump to end if we're done (likely?). */
s390_emit_jump (csend, s390_emit_compare (EQ, cmpv, ac.memsi));
s390_emit_jump (csend, s390_emit_compare_and_swap (EQ, res, ac.memsi,
cmpv, newv));
/* Check for changes outside mode. */
resv = expand_simple_binop (SImode, AND, res, ac.modemaski,
@ -4284,13 +4300,9 @@ s390_expand_atomic (enum machine_mode mode, enum rtx_code code,
default:
gcc_unreachable ();
}
/* Emit compare_and_swap pattern. */
emit_insn (gen_sync_compare_and_swap_ccsi (cmp, ac.memsi, cmp, new));
/* Loop until swapped (unlikely?). */
s390_emit_jump (csloop, gen_rtx_fmt_ee (NE, CCZ1mode,
gen_rtx_REG (CCZ1mode, CC_REGNUM),
const0_rtx));
s390_emit_jump (csloop, s390_emit_compare_and_swap (NE, cmp,
ac.memsi, cmp, new));
/* Return the correct part of the bitfield. */
if (target)

View File

@ -1,3 +1,7 @@
2006-11-24 Andreas Krebbel <krebbel1@de.ibm.com>
* gcc.dg/20061124-1.c: New testcase.
2006-11-23 Eric Christopher <echristo@apple.com>
* gcc.dg/inline-16.c: Use __SIZE_TYPE__.

View File

@ -0,0 +1,19 @@
/* { dg-do run } */
/* { dg-require-effective-target sync_char_short } */
/* This testcase failed on s390 because no compare instruction for
the check of FLAG was emitted. */
unsigned short int count = 0;
int flag = 1;
extern void abort (void);
int
main ()
{
__sync_add_and_fetch (&count, -1);
if (!flag)
abort ();
}