From 8bb501bb101f74c9c02e949edad65f07615e27d0 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 24 Nov 2006 13:30:59 +0000 Subject: [PATCH] s390.c (s390_emit_compare_and_swap): New function. 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. From-SVN: r119151 --- gcc/ChangeLog | 6 ++++++ gcc/config/s390/s390.c | 32 +++++++++++++++++++++---------- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/gcc.dg/20061124-1.c | 19 ++++++++++++++++++ 4 files changed, 51 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20061124-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c671d35a3292..a79d14b7c5d5 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 59baba9f3de5..cfe959e88f0e 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 ae246a191b6f..b97aa166ac5c 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 000000000000..14d04395e388 --- /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 (); +} -- 2.47.2