From patchwork Sun Feb 1 11:18:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Endo X-Patchwork-Id: 435220 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id B3F0D140182 for ; Sun, 1 Feb 2015 22:19:10 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:subject:from:to:date:content-type:mime-version; q= dns; s=default; b=YOQW115/BnbIuMJWxCWV2NqrH+Cgz1TOWwN+Cp1gCMr2ur Kykz2ywUROLM9LepyiDsPVZ2baXYILvKH1TSl2LRGEA+DdjEQAkZAT5Lr4TAKIER BP6niX2eQme6GbBG8FMnd71hj5LeJiWm1yueDzI8eN4f6oq5n5086+veZPvjY= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:subject:from:to:date:content-type:mime-version; s= default; bh=OgbznQBkOqi4ToiN419lRqlE8Xk=; b=kl5FXFKtp52i4OkybUSf CiY3JJi29xSCllwC7Co+9iplxQcRjdpEi2RSkkh+dfOJ5eFVAfJrZvYSzH2ukIdZ vvA7oZ/aPX9PGZnaHDGDbznoLsmUK7gbBzVrseHBYn4rilazQ9ABk2+WcCiI0AiG UnXxKVFusVrM5yj4vqrBkJI= Received: (qmail 29048 invoked by alias); 1 Feb 2015 11:18:36 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 29029 invoked by uid 89); 1 Feb 2015 11:18:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_BL_SPAMCOP_NET, RCVD_IN_DNSWL_NONE, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mailout12.t-online.de Received: from mailout12.t-online.de (HELO mailout12.t-online.de) (194.25.134.22) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Sun, 01 Feb 2015 11:18:33 +0000 Received: from fwd18.aul.t-online.de (fwd18.aul.t-online.de [172.20.26.244]) by mailout12.t-online.de (Postfix) with SMTP id 0FCD6364B0E for ; Sun, 1 Feb 2015 12:18:28 +0100 (CET) Received: from [192.168.0.105] (bdHTPTZeghFp5nYV+J6iyRR5iPV0wf97pULZtx2JqXmZpYBWOvKTUYjb6qE+INrZM2@[84.180.120.77]) by fwd18.t-online.de with (TLSv1.2:ECDHE-RSA-AES256-SHA encrypted) esmtp id 1YHsXo-0QJkDQ0; Sun, 1 Feb 2015 12:18:24 +0100 Message-ID: <1422789503.25265.19.camel@yam-132-YW-E178-FTW> Subject: [SH][committed] Add atomic not insns From: Oleg Endo To: gcc-patches Date: Sun, 01 Feb 2015 12:18:23 +0100 Mime-Version: 1.0 X-IsSubscribed: yes Hi, This adds atomic not insns for SH. Although not directly supported by the atomic builtins, for things like atomic xor (-1) or atomic nand (-1) combine will happily try to simplify the insns into a unary not. Committed as r220317. Tested with make -k check-gcc RUNTESTFLAGS="sh.exp=pr64851* --target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m2e/-ml,-m2e/-mb,-m3/-ml,-m3/-mb,-m3e/-ml,-m3e/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" to verify that the insns actually work. Will observe daily sh4-linux test results for fallouts. Cheers, Oleg gcc/ChangeLog: PR target/64851 * config/sh/sync.md (atomic_fetch_notsi_hard, atomic_fetch_not_hard, atomic_fetch_not_soft_gusa, atomic_fetch_not_soft_tcb, atomic_fetch_not_soft_imask, atomic_not_fetchsi_hard, atomic_not_fetch_hard, atomic_not_fetch_soft_gusa, atomic_not_fetch_soft_tcb, atomic_not_fetch_soft_imask): New insns. gcc/testsuite/ChangeLog: PR target/64851 * gcc.target/sh/pr64851-0.h: New * gcc.target/sh/pr64851-1.c: New * gcc.target/sh/pr64851-2.c: New * gcc.target/sh/pr64851-3.c: New * gcc.target/sh/pr64851-4.c: New Index: gcc/config/sh/sync.md =================================================================== --- gcc/config/sh/sync.md (revision 220260) +++ gcc/config/sh/sync.md (working copy) @@ -673,6 +673,25 @@ } [(set_attr "length" "10")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_fetch_notsi_hard" + [(set (match_operand:SI 0 "arith_reg_dest" "=&r") + (mem:SI (match_operand:SI 1 "arith_reg_operand" "r"))) + (set (mem:SI (match_dup 1)) + (unspec:SI [(not:SI (mem:SI (match_dup 1)))] UNSPEC_ATOMIC)) + (set (reg:SI T_REG) (const_int 1)) + (clobber (reg:SI R0_REG))] + "TARGET_ATOMIC_HARD_LLCS + || (TARGET_SH4A && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)" +{ + return "\r0: movli.l @%1,r0" "\n" + " mov r0,%0" "\n" + " not r0,r0" "\n" + " movco.l r0,@%1" "\n" + " bf 0b"; +} + [(set_attr "length" "10")]) + (define_insn "atomic_fetch__hard" [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r") (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))) @@ -705,6 +724,34 @@ } [(set_attr "length" "28")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_fetch_not_hard" + [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r") + (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r"))) + (set (mem:QIHI (match_dup 1)) + (unspec:QIHI [(not:QIHI (mem:QIHI (match_dup 1)))] UNSPEC_ATOMIC)) + (set (reg:SI T_REG) (const_int 1)) + (clobber (reg:SI R0_REG)) + (clobber (match_scratch:SI 2 "=&r")) + (clobber (match_scratch:SI 3 "=1"))] + "TARGET_ATOMIC_HARD_LLCS" +{ + return "\r mov #-4,%2" "\n" + " and %1,%2" "\n" + " xor %2,%1" "\n" + " add r15,%1" "\n" + " add #-4,%1" "\n" + "0: movli.l @%2,r0" "\n" + " mov.l r0,@-r15" "\n" + " mov. @%1,%0" "\n" + " not %0,r0" "\n" + " mov. r0,@%1" "\n" + " mov.l @r15+,r0" "\n" + " movco.l r0,@%2" "\n" + " bf 0b"; +} + [(set_attr "length" "26")]) + (define_insn "atomic_fetch__soft_gusa" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u") (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))) @@ -732,6 +779,28 @@ } [(set_attr "length" "18")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_fetch_not_soft_gusa" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u") + (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u"))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (clobber (match_scratch:QIHISI 2 "=&u")) + (clobber (reg:SI R0_REG)) + (clobber (reg:SI R1_REG))] + "TARGET_ATOMIC_SOFT_GUSA" +{ + return "\r mova 1f,r0" "\n" + " mov r15,r1" "\n" + " .align 2" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " not %0,%2" "\n" + " mov. %2,@%1" "\n" + "1: mov r1,r15"; +} + [(set_attr "length" "16")]) + (define_insn "atomic_fetch__soft_tcb" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))) @@ -760,6 +829,30 @@ } [(set_attr "length" "20")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_fetch_not_soft_tcb" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") + (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (use (match_operand:SI 2 "gbr_displacement")) + (clobber (reg:SI R0_REG)) + (clobber (reg:SI R1_REG))] + "TARGET_ATOMIC_SOFT_TCB" +{ + return "\r mova 1f,r0" "\n" + " .align 2" "\n" + " mov #(0f-1f),r1" "\n" + " mov.l r0,@(%O2,gbr)" "\n" + "0: mov. @%1,r0" "\n" + " mov r0,%0" "\n" + " not r0,r0" "\n" + " mov. r0,@%1" "\n" + "1: mov #0,r0" "\n" + " mov.l r0,@(%O2,gbr)"; +} + [(set_attr "length" "20")]) + (define_insn "atomic_fetch__soft_imask" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))) @@ -786,6 +879,28 @@ } [(set_attr "length" "18")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_fetch_not_soft_imask" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") + (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r"))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (clobber (reg:SI R0_REG)) + (clobber (match_scratch:QIHISI 2 "=&r"))] + "TARGET_ATOMIC_SOFT_IMASK" +{ + return "\r stc sr,r0" "\n" + " mov r0,%2" "\n" + " or #0xF0,r0" "\n" + " ldc r0,sr" "\n" + " mov. @%1,r0" "\n" + " mov r0,%0" "\n" + " not r0,r0" "\n" + " mov. r0,@%1" "\n" + " ldc %2,sr"; +} + [(set_attr "length" "18")]) + (define_expand "atomic_fetch_nand" [(set (match_operand:QIHISI 0 "arith_reg_dest") (match_operand:QIHISI 1 "memory_operand")) @@ -1028,6 +1143,23 @@ } [(set_attr "length" "8")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_not_fetchsi_hard" + [(set (match_operand:SI 0 "arith_reg_dest" "=&z") + (not:SI (mem:SI (match_operand:SI 1 "arith_reg_operand" "r")))) + (set (mem:SI (match_dup 1)) + (unspec:SI [(not:SI (mem:SI (match_dup 1)))] UNSPEC_ATOMIC)) + (set (reg:SI T_REG) (const_int 1))] + "TARGET_ATOMIC_HARD_LLCS + || (TARGET_SH4A && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)" +{ + return "\r0: movli.l @%1,%0" "\n" + " not %0,%0" "\n" + " movco.l %0,@%1" "\n" + " bf 0b"; +} + [(set_attr "length" "8")]) + (define_insn "atomic__fetch_hard" [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r") (FETCHOP:QIHI @@ -1061,6 +1193,35 @@ } [(set_attr "length" "28")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_not_fetch_hard" + [(set (match_operand:QIHI 0 "arith_reg_dest" "=&r") + (not:QIHI (mem:QIHI (match_operand:SI 1 "arith_reg_operand" "r")))) + (set (mem:QIHI (match_dup 1)) + (unspec:QIHI [(not:QIHI (mem:QIHI (match_dup 1)))] UNSPEC_ATOMIC)) + (set (reg:SI T_REG) (const_int 1)) + (clobber (reg:SI R0_REG)) + (clobber (match_scratch:SI 2 "=&r")) + (clobber (match_scratch:SI 3 "=1"))] + "TARGET_ATOMIC_HARD_LLCS" +{ + return "\r mov #-4,%2" "\n" + " and %1,%2" "\n" + " xor %2,%1" "\n" + " add r15,%1" "\n" + " add #-4,%1" "\n" + "0: movli.l @%2,r0" "\n" + " mov.l r0,@-r15" "\n" + " mov. @%1,r0" "\n" + " not r0,r0" "\n" + " mov. r0,@%1" "\n" + " mov r0,%0" "\n" + " mov.l @r15+,r0" "\n" + " movco.l r0,@%2" "\n" + " bf 0b"; +} + [(set_attr "length" "28")]) + (define_insn "atomic__fetch_soft_gusa" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u") (FETCHOP:QIHISI @@ -1086,6 +1247,27 @@ } [(set_attr "length" "16")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_not_fetch_soft_gusa" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&u") + (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "u")))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (clobber (reg:SI R0_REG)) + (clobber (reg:SI R1_REG))] + "TARGET_ATOMIC_SOFT_GUSA" +{ + return "\r mova 1f,r0" "\n" + " mov r15,r1" "\n" + " .align 2" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " not %0,%0" "\n" + " mov. %0,@%1" "\n" + "1: mov r1,r15"; +} + [(set_attr "length" "16")]) + (define_insn "atomic__fetch_soft_tcb" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") (FETCHOP:QIHISI @@ -1114,6 +1296,30 @@ } [(set_attr "length" "20")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_not_fetch_soft_tcb" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&r") + (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (clobber (reg:SI R0_REG)) + (clobber (reg:SI R1_REG)) + (use (match_operand:SI 2 "gbr_displacement"))] + "TARGET_ATOMIC_SOFT_TCB" +{ + return "\r mova 1f,r0" "\n" + " mov #(0f-1f),r1" "\n" + " .align 2" "\n" + " mov.l r0,@(%O2,gbr)" "\n" + "0: mov. @%1,r0" "\n" + " not r0,r0" "\n" + " mov. r0,@%1" "\n" + "1: mov r0,%0" "\n" + " mov #0,r0" "\n" + " mov.l r0,@(%O2,gbr)"; +} + [(set_attr "length" "20")]) + (define_insn "atomic__fetch_soft_imask" [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z") (FETCHOP:QIHISI @@ -1138,6 +1344,26 @@ } [(set_attr "length" "16")]) +;; Combine pattern for xor (val, -1) / nand (val, -1). +(define_insn "atomic_not_fetch_soft_imask" + [(set (match_operand:QIHISI 0 "arith_reg_dest" "=&z") + (not:QIHISI (mem:QIHISI (match_operand:SI 1 "arith_reg_operand" "r")))) + (set (mem:QIHISI (match_dup 1)) + (unspec:QIHISI [(not:QIHISI (mem:QIHISI (match_dup 1)))] UNSPEC_ATOMIC)) + (clobber (match_scratch:SI 2 "=&r"))] + "TARGET_ATOMIC_SOFT_IMASK" +{ + return "\r stc sr,%0" "\n" + " mov %0,%2" "\n" + " or #0xF0,%0" "\n" + " ldc %0,sr" "\n" + " mov. @%1,%0" "\n" + " not %0,%0" "\n" + " mov. %0,@%1" "\n" + " ldc %2,sr"; +} + [(set_attr "length" "16")]) + (define_expand "atomic_nand_fetch" [(set (match_operand:QIHISI 0 "arith_reg_dest") (not:QIHISI (and:QIHISI Index: gcc/testsuite/gcc.target/sh/pr64851-2.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr64851-2.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64851-2.c (revision 0) @@ -0,0 +1,6 @@ +/* Check that atomic not ops are generated. */ +/* { dg-do compile { target { atomic_model_soft_tcb_available } } } */ +/* { dg-options "-O2 -matomic-model=soft-tcb,gbr-offset=0,strict" } */ +/* { dg-final { scan-assembler-times "not\t" 12 } } */ + +#include "pr64851-0.h" Index: gcc/testsuite/gcc.target/sh/pr64851-3.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr64851-3.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64851-3.c (revision 0) @@ -0,0 +1,6 @@ +/* Check that atomic not ops are generated. */ +/* { dg-do compile { target { atomic_model_soft_imask_available } } } */ +/* { dg-options "-O2 -matomic-model=soft-imask,strict -mno-usermode" } */ +/* { dg-final { scan-assembler-times "not\t" 12 } } */ + +#include "pr64851-0.h" Index: gcc/testsuite/gcc.target/sh/pr64851-4.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr64851-4.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64851-4.c (revision 0) @@ -0,0 +1,6 @@ +/* Check that atomic not ops are generated. */ +/* { dg-do compile { target { atomic_model_hard_llcs_available } } } */ +/* { dg-options "-O2 -matomic-model=hard-llcs,strict" } */ +/* { dg-final { scan-assembler-times "not\t" 12 } } */ + +#include "pr64851-0.h" Index: gcc/testsuite/gcc.target/sh/pr64851-0.h =================================================================== --- gcc/testsuite/gcc.target/sh/pr64851-0.h (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64851-0.h (revision 0) @@ -0,0 +1,21 @@ +/* Check that atomic not ops are generated. */ + +#define emitfuncs(name)\ + void test_ ## name ## _0 (char* mem)\ + {\ + name (mem, -1, __ATOMIC_ACQ_REL);\ + }\ + void test_ ## name ## _1 (short* mem)\ + {\ + name (mem, -1, __ATOMIC_ACQ_REL);\ + }\ + void test_ ## name ##_2 (int* mem)\ + {\ + name (mem, -1, __ATOMIC_ACQ_REL);\ + }\ + +emitfuncs (__atomic_xor_fetch) +emitfuncs (__atomic_fetch_xor) + +emitfuncs (__atomic_nand_fetch) +emitfuncs (__atomic_fetch_nand) Index: gcc/testsuite/gcc.target/sh/pr64851-1.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr64851-1.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64851-1.c (revision 0) @@ -0,0 +1,6 @@ +/* Check that atomic not ops are generated. */ +/* { dg-do compile { target { atomic_model_soft_gusa_available } } } */ +/* { dg-options "-O2 -matomic-model=soft-gusa,strict" } */ +/* { dg-final { scan-assembler-times "not\t" 12 } } */ + +#include "pr64851-0.h"