diff options
author | Andreas Krebbel <krebbel1@de.ibm.com> | 2006-11-24 13:30:59 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@gcc.gnu.org> | 2006-11-24 13:30:59 +0000 |
commit | 8bb501bb101f74c9c02e949edad65f07615e27d0 (patch) | |
tree | a5a7094da9c34bd39de801a48073299a8a714627 | |
parent | af1e323e93b86d33d9474dcdb64774b5e8c258e8 (diff) | |
download | gcc-8bb501bb101f74c9c02e949edad65f07615e27d0.zip gcc-8bb501bb101f74c9c02e949edad65f07615e27d0.tar.gz gcc-8bb501bb101f74c9c02e949edad65f07615e27d0.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 32 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/20061124-1.c | 19 |
4 files changed, 51 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c671d35..a79d14b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 59baba9..cfe959e 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 ae246a1..b97aa16 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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__. diff --git a/gcc/testsuite/gcc.dg/20061124-1.c b/gcc/testsuite/gcc.dg/20061124-1.c new file mode 100644 index 0000000..14d0439 --- /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 (); +} |