From f66f986566478b3efd0ad17cb0bc969709c8a54c Mon Sep 17 00:00:00 2001 From: David Edelsohn Date: Sat, 29 Nov 2008 21:24:03 +0000 Subject: [PATCH] rs6000.c (rs6000_emit_sync): Remove support for operand wrapped in NOT. * config/rs6000/rs6000.c (rs6000_emit_sync): Remove support for operand wrapped in NOT. Emit NAND as (ior (not X) (not Y)). (rs6000_split_atomic_op): Emit NAND as (ior (not X) (not Y)). * config/rs6000/sync.md (sync_nand): Represent NAND in RTL. Call rs6000_emit_sync with CODE=NOT and unmodified operands. Ignore sub-word case for now. (sync_nand_internal): Represent NAND in RTL. (sync_old_nand_internal): Same. (sync_new_nand): Same. (sync_new_nand_internal): Same. (sync_boolcshort_internal): Expect NAND. From-SVN: r142285 --- gcc/ChangeLog | 15 +++++++++++ gcc/config/rs6000/rs6000.c | 38 ++++++++++++---------------- gcc/config/rs6000/sync.md | 52 ++++++++++++++++++-------------------- 3 files changed, 56 insertions(+), 49 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 615aad2f7c1..392b0249f3d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2008-11-29 David Edelsohn + + * config/rs6000/rs6000.c (rs6000_emit_sync): Remove support for + operand wrapped in NOT. Emit NAND as (ior (not X) (not Y)). + (rs6000_split_atomic_op): Emit NAND as (ior (not X) (not Y)). + * config/rs6000/sync.md (sync_nand): Represent NAND in RTL. + Call rs6000_emit_sync with CODE=NOT and unmodified operands. + Ignore sub-word case for now. + (sync_nand_internal): Represent NAND in RTL. + (sync_old_nand_internal): Same. + (sync_new_nand): Same. + (sync_new_nand_internal): Same. + (sync_boolcshort_internal): Expect NAND. + 2008-11-28 Richard Guenther PR tree-optimization/37955 diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 46b1be0c8c4..e2d8ddc0003 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -13826,9 +13826,6 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode, if (sync_p) emit_insn (gen_lwsync ()); - if (GET_CODE (m) == NOT) - used_m = XEXP (m, 0); - else used_m = m; /* If this is smaller than SImode, we'll have to use SImode with @@ -13870,10 +13867,7 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode, /* It's safe to keep the old alias set of USED_M, because the operation is atomic and only affects the original USED_M. */ - if (GET_CODE (m) == NOT) - m = gen_rtx_NOT (SImode, used_m); - else - m = used_m; + m = used_m; if (GET_CODE (op) == NOT) { @@ -13893,6 +13887,13 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode, emit_insn (gen_ashlsi3 (newop, newop, shift)); break; + case NOT: /* NAND */ + newop = expand_binop (SImode, ior_optab, + oldop, GEN_INT (~imask), NULL_RTX, + 1, OPTAB_LIB_WIDEN); + emit_insn (gen_rotlsi3 (newop, newop, shift)); + break; + case AND: newop = expand_binop (SImode, ior_optab, oldop, GEN_INT (~imask), NULL_RTX, @@ -13930,19 +13931,6 @@ 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); @@ -13960,11 +13948,15 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode, after = gen_reg_rtx (used_mode); } - if ((code == PLUS || code == MINUS || GET_CODE (m) == NOT) + if ((code == PLUS || code == MINUS) && 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); + else if (code == NOT) + the_op = gen_rtx_fmt_ee (IOR, used_mode, + gen_rtx_NOT (used_mode, m), + gen_rtx_NOT (used_mode, op)); else the_op = gen_rtx_fmt_ee (code, used_mode, m, op); @@ -14075,7 +14067,9 @@ rs6000_split_atomic_op (enum rtx_code code, rtx mem, rtx val, emit_load_locked (mode, before, mem); if (code == NOT) - x = gen_rtx_AND (mode, gen_rtx_NOT (mode, before), val); + x = gen_rtx_IOR (mode, + gen_rtx_NOT (mode, before), + gen_rtx_NOT (mode, val)); else if (code == AND) x = gen_rtx_UNSPEC (mode, gen_rtvec (2, before, val), UNSPEC_AND); else diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md index 58397154645..0adc23cfc04 100644 --- a/gcc/config/rs6000/sync.md +++ b/gcc/config/rs6000/sync.md @@ -210,8 +210,8 @@ (define_expand "sync_nand" [(parallel [(set (match_operand:INT1 0 "memory_operand" "") (unspec:INT1 - [(and:INT1 (not:INT1 (match_dup 0)) - (match_operand:INT1 1 "gpc_reg_operand" ""))] + [(ior:INT1 (not:INT1 (match_dup 0)) + (not:INT1 (match_operand:INT1 1 "gpc_reg_operand" "")))] UNSPEC_ATOMIC)) (clobber (scratch:INT1)) (clobber (scratch:CC))])] @@ -220,11 +220,10 @@ { if (mode != SImode && mode != DImode) { + FAIL; if (PPC405_ERRATUM77) FAIL; - rs6000_emit_sync (AND, mode, - gen_rtx_NOT (mode, operands[0]), - operands[1], + rs6000_emit_sync (NOT, mode, operands[0], operands[1], NULL_RTX, NULL_RTX, true); DONE; } @@ -233,8 +232,8 @@ (define_insn_and_split "*sync_nand_internal" [(set (match_operand:GPR 0 "memory_operand" "+Z") (unspec:GPR - [(and:GPR (not:GPR (match_dup 0)) - (match_operand:GPR 1 "gpc_reg_operand" "r"))] + [(ior:GPR (not:GPR (match_dup 0)) + (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] UNSPEC_ATOMIC)) (clobber (match_scratch:GPR 2 "=&r")) (clobber (match_scratch:CC 3 "=&x"))] @@ -316,8 +315,8 @@ (match_operand:INT1 1 "memory_operand" "")) (set (match_dup 1) (unspec:INT1 - [(and:INT1 (not:INT1 (match_dup 1)) - (match_operand:INT1 2 "gpc_reg_operand" ""))] + [(ior:INT1 (not:INT1 (match_dup 1)) + (not:INT1 (match_operand:INT1 2 "gpc_reg_operand" "")))] UNSPEC_ATOMIC)) (clobber (scratch:INT1)) (clobber (scratch:CC))])] @@ -326,11 +325,10 @@ { if (mode != SImode && mode != DImode) { + FAIL; if (PPC405_ERRATUM77) FAIL; - rs6000_emit_sync (AND, mode, - gen_rtx_NOT (mode, operands[1]), - operands[2], + rs6000_emit_sync (NOT, mode, operands[1], operands[2], operands[0], NULL_RTX, true); DONE; } @@ -341,8 +339,8 @@ (match_operand:GPR 1 "memory_operand" "+Z")) (set (match_dup 1) (unspec:GPR - [(and:GPR (not:GPR (match_dup 1)) - (match_operand:GPR 2 "gpc_reg_operand" "r"))] + [(ior:GPR (not:GPR (match_dup 1)) + (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")))] UNSPEC_ATOMIC)) (clobber (match_scratch:GPR 3 "=&r")) (clobber (match_scratch:CC 4 "=&x"))] @@ -424,12 +422,13 @@ (define_expand "sync_new_nand" [(parallel [(set (match_operand:INT1 0 "gpc_reg_operand" "") - (and:INT1 + (ior:INT1 (not:INT1 (match_operand:INT1 1 "memory_operand" "")) - (match_operand:INT1 2 "gpc_reg_operand" ""))) + (not:INT1 (match_operand:INT1 2 "gpc_reg_operand" "")))) (set (match_dup 1) (unspec:INT1 - [(and:INT1 (not:INT1 (match_dup 1)) (match_dup 2))] + [(ior:INT1 (not:INT1 (match_dup 1)) + (not:INT1 (match_dup 2)))] UNSPEC_ATOMIC)) (clobber (scratch:INT1)) (clobber (scratch:CC))])] @@ -438,11 +437,10 @@ { if (mode != SImode && mode != DImode) { + FAIL; if (PPC405_ERRATUM77) FAIL; - rs6000_emit_sync (AND, mode, - gen_rtx_NOT (mode, operands[1]), - operands[2], + rs6000_emit_sync (NOT, mode, operands[1], operands[2], NULL_RTX, operands[0], true); DONE; } @@ -450,12 +448,12 @@ (define_insn_and_split "*sync_new_nand_internal" [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") - (and:GPR + (ior:GPR (not:GPR (match_operand:GPR 1 "memory_operand" "+Z")) - (match_operand:GPR 2 "gpc_reg_operand" "r"))) + (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")))) (set (match_dup 1) (unspec:GPR - [(and:GPR (not:GPR (match_dup 1)) (match_dup 2))] + [(ior:GPR (not:GPR (match_dup 1)) (not:GPR (match_dup 2)))] UNSPEC_ATOMIC)) (clobber (match_scratch:GPR 3 "=&r")) (clobber (match_scratch:CC 4 "=&x"))] @@ -580,10 +578,10 @@ ; Likewise, operand 5 is in practice 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")])) + (match_operator:SI 4 "boolean_or_operator" + [(xor:SI (not:SI (match_operand:SI 0 "memory_operand" "+Z")) + (not:SI (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"))]