From: krebbel Date: Fri, 24 Nov 2006 13:30:59 +0000 (+0000) Subject: 2006-11-24 Andreas Krebbel X-Git-Url: http://git.sourceforge.jp/view?a=commitdiff_plain;h=db1f11e3bd8fa6e281e05e85b1110ef6de2a957b;p=pf3gnuchains%2Fgcc-fork.git 2006-11-24 Andreas Krebbel * 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 * gcc.dg/20061124-1.c: New testcase. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@119151 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c671d35a329..a79d14b7c5d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2006-11-24 Andreas Krebbel + + * 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 * pa.c (return_addr_rtx): Change 0xe0400002 to -532676606. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 59baba9f3de..cfe959e88f0 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ae246a191b6..b97aa166ac5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2006-11-24 Andreas Krebbel + + * gcc.dg/20061124-1.c: New testcase. + 2006-11-23 Eric Christopher * gcc.dg/inline-16.c: Use __SIZE_TYPE__. diff --git a/gcc/testsuite/gcc.dg/20061124-1.c b/gcc/testsuite/gcc.dg/20061124-1.c new file mode 100644 index 00000000000..14d04395e38 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20061124-1.c @@ -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 (); +}