From patchwork Wed Dec 21 14:43:22 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oleg Endo X-Patchwork-Id: 132670 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]) by ozlabs.org (Postfix) with SMTP id 8C576B7127 for ; Thu, 22 Dec 2011 01:44:00 +1100 (EST) Received: (qmail 7997 invoked by alias); 21 Dec 2011 14:43:57 -0000 Received: (qmail 7978 invoked by uid 22791); 21 Dec 2011 14:43:54 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SARE_HTML_INV_TAG, UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Received: from mailout09.t-online.de (HELO mailout09.t-online.de) (194.25.134.84) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 21 Dec 2011 14:43:39 +0000 Received: from fwd19.aul.t-online.de (fwd19.aul.t-online.de ) by mailout09.t-online.de with smtp id 1RdNOL-0001u0-2K; Wed, 21 Dec 2011 15:43:37 +0100 Received: from [192.168.0.104] (G-Suw-ZHohF6u6O0+2bK3Ir8dCQFRFzkR6C5ZTK9ne77nuRHNUCG+PxNfZlNlY3gQ5@[93.218.168.85]) by fwd19.t-online.de with esmtp id 1RdNO8-036lHc0; Wed, 21 Dec 2011 15:43:24 +0100 Subject: Re: [patch committed SH] Add atomic patterns From: Oleg Endo To: Kaz Kojima Cc: gcc-patches@gcc.gnu.org In-Reply-To: <1324248440.18753.390.camel@yam-132-YW-E178-FTW> References: <1324152819.18753.322.camel@yam-132-YW-E178-FTW> <20111218.091549.446387858.kkojima@rr.iij4u.or.jp> <1324211730.18753.365.camel@yam-132-YW-E178-FTW> <20111219.071356.13624366.kkojima@rr.iij4u.or.jp> <1324248440.18753.390.camel@yam-132-YW-E178-FTW> Date: Wed, 21 Dec 2011 15:43:22 +0100 Message-ID: <1324478602.18753.540.camel@yam-132-YW-E178-FTW> Mime-Version: 1.0 X-IsSubscribed: yes 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 > > Ugh, I've read the middle end code wrongly. Then we can remove > > fetchop_insn which now becomes to be the same one with fetchop_name. > > Could you propose the patch with that change and the backslash > > changes rth suggested? It's pre-approved with those changes. > > Attached patch should do. Cheers, Oleg 2011-12-21 Oleg Endo * config/sh/sync.md: Add soft atomics ABI description. (fetchop_name): Use 'or' instead of 'ior'. (fetchop_insn): Remove. (atomic_compare_and_swap_soft): Don't insert aligning nop after the write-back instruction. Fix multi-line asm output formatting style. (atomic_fetch__soft): Likewise. (atomic_fetch_nand_soft): Likewise. (atomic__fetch_soft): Likewise. (atomic_nand_fetch_soft): Likewise. Index: gcc/config/sh/sync.md =================================================================== --- gcc/config/sh/sync.md (revision 182531) +++ gcc/config/sh/sync.md (working copy) @@ -17,6 +17,77 @@ ;; You should have received a copy of the GNU General Public License ;; along with GCC; see the file COPYING3. If not see ;; . +;; +;; +;; Atomic integer operations for the Renesas / SuperH SH CPUs. +;; +;; On single-core systems there can only be one execution context running +;; at a given point in time. This allows the usage of rewindable atomic +;; sequences, which effectively emulate locked-load / conditional-store +;; operations. +;; When an execution context is interrupted while it is an atomic +;; sequence, the interrupted context's PC is rewound to the beginning of +;; the atomic sequence by the interrupt / exception handling code, before +;; transferring control to another execution context. This is done by +;; something like... +;; +;; if (interrupted_context_in_atomic_sequence +;; && interrupted_pc < atomic_exitpoint) +;; interrupted_pc = atomic_entrypoint; +;; +;; This method is also known as gUSA ("g" User Space Atomicity) and the +;; Linux kernel for SH3/SH4 implements support for such software +;; atomic sequences. However, it can also be implemented in freestanding +;; environments. +;; +;; For this the following atomic sequence ABI is used. +;; +;; r15 >= 0: Execution context is not in an atomic sequence. +;; +;; r15 < 0: Execution context is in an atomic sequence and r15 +;; holds the negative byte length of the atomic sequence. +;; In this case the following applies: +;; +;; r0: PC of the first instruction after the atomic +;; write-back instruction (exit point). +;; The entry point PC of the atomic sequence can be +;; determined by doing r0 + r15. +;; +;; r1: Saved r15 stack pointer before entering the +;; atomic sequence. +;; +;; An example atomic add sequence would look like: +;; +;; mova .Lend,r0 ! .Lend must be 4-byte aligned. +;; mov r15,r1 +;; .align 2 ! Insert aligning nop if needed. +;; mov #(.Lstart - .Lend),r15 ! Enter atomic sequence +;;.Lstart: +;; mov.l @r4,r2 ! read value +;; add r2,r5 ! modify value +;; mov.l r5,@r4 ! write-back +;;.Lend: +;; mov r1,r15 ! Exit atomic sequence +;; ! r2 holds the previous value. +;; ! r5 holds the new value. +;; +;; Notice that due to the restrictions of the mova instruction, the .Lend +;; label must always be 4-byte aligned. Aligning the .Lend label would +;; potentially insert a nop after the write-back instruction which could +;; make the sequence to be rewound, although it has already passed the +;; write-back instruction. This would make it execute twice. +;; For correct operation the atomic sequences must not be rewound after +;; they have passed the write-back instruction. +;; +;; The current implementation is limited to QImode, HImode and SImode +;; atomic operations. DImode operations could also be implemented but +;; would require some ABI modifications to support multiple-instruction +;; write-back. This is because SH1/SH2/SH3/SH4 does not have a DImode +;; store instruction. DImode stores must be split into two SImode stores. +;; +;; For some operations it would be possible to use insns with an immediate +;; operand such as add #imm,Rn. However, since the original value before +;; the operation also needs to be available, this is not so handy. (define_c_enum "unspec" [ UNSPEC_ATOMIC @@ -35,14 +106,8 @@ (define_code_iterator FETCHOP [plus minus ior xor and]) (define_code_attr fetchop_name - [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")]) -(define_code_attr fetchop_insn [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")]) -;; Linux specific atomic patterns for the Renesas / SuperH SH CPUs. -;; Linux kernel for SH3/4 has implemented the support for software -;; atomic sequences. - (define_expand "atomic_compare_and_swap" [(match_operand:QI 0 "register_operand" "") ;; bool success output (match_operand:I124 1 "register_operand" "") ;; oldval output @@ -85,20 +150,18 @@ (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG))] "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" - "* { - return \"\\ -mova\\t1f, r0\\n\\ -\\t\\t%2, %4\\n\\ -\\tmov\\tr15, r1\\n\\ -\\tmov\\t#(0f-1f), r15\\n\\ -0:\\tmov.\\t@%1, %0\\n\\ -\\tcmp/eq\\t%0, %4\\n\\ -\\tbf\\t1f\\n\\ -\\tmov.\\t%3, @%1\\n\\ -\\t.align\\t2\\n\\ -1:\\tmov\tr1, r15\"; -}" + return "mova 1f,r0" "\n" + " %2,%4" "\n" + " .align 2" "\n" + " mov r15,r1" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " cmp/eq %0,%4" "\n" + " bf 1f" "\n" + " mov. %3,@%1" "\n" + "1: mov r1,r15"; +} [(set_attr "length" "20")]) (define_expand "atomic_fetch_" @@ -138,19 +201,17 @@ (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG))] "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" - "* { - return \"\\ -mova\\t1f, r0\\n\\ -\\tmov\\tr15, r1\\n\\ -\\tmov\\t#(0f-1f), r15\\n\\ -0:\\tmov.\\t@%1, %0\\n\\ -\\tmov\\t%0, %3\\n\\ -\\t\\t%2, %3\\n\\ -\\tmov.\\t%3, @%1\\n\\ -\\t.align\\t2\\n\\ -1:\\tmov\tr1, r15\"; -}" + return "mova 1f,r0" "\n" + " .align 2" "\n" + " mov r15,r1" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " mov %0,%3" "\n" + " %2,%3" "\n" + " mov. %3,@%1" "\n" + "1: mov r1,r15"; +} [(set_attr "length" "18")]) (define_expand "atomic_fetch_nand" @@ -190,20 +251,18 @@ (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG))] "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" - "* { - return \"\\ -mova\\t1f, r0\\n\\ -\\tmov\\tr15, r1\\n\\ -\\tmov\\t#(0f-1f), r15\\n\\ -0:\\tmov.\\t@%1, %0\\n\\ -\\tmov\\t%2, %3\\n\\ -\\tand\\t%0, %3\\n\\ -\\tnot\\t%3, %3\\n\\ -\\tmov.\\t%3, @%1\\n\\ -\\t.align\\t2\\n\\ -1:\\tmov\tr1, r15\"; -}" + return "mova 1f,r0" "\n" + " mov r15,r1" "\n" + " .align 2" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " mov %2,%3" "\n" + " and %0,%3" "\n" + " not %3,%3" "\n" + " mov. %3,@%1" "\n" + "1: mov r1,r15"; +} [(set_attr "length" "20")]) (define_expand "atomic__fetch" @@ -244,18 +303,16 @@ (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG))] "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" - "* { - return \"\\ -mova\\t1f, r0\\n\\ -\\tmov\\tr15, r1\\n\\ -\\tmov\\t#(0f-1f), r15\\n\\ -0:\\tmov.\\t@%1, %0\\n\\ -\\t\\t%2, %0\\n\\ -\\tmov.\\t%0, @%1\\n\\ -\\t.align\\t2\\n\\ -1:\\tmov\tr1, r15\"; -}" + return "mova 1f,r0" "\n" + " mov r15,r1" "\n" + " .align 2" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " %2,%0" "\n" + " mov. %0,@%1" "\n" + "1: mov r1,r15"; +} [(set_attr "length" "16")]) (define_expand "atomic_nand_fetch" @@ -296,17 +353,15 @@ (clobber (reg:SI R0_REG)) (clobber (reg:SI R1_REG))] "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA" - "* { - return \"\\ -mova\\t1f, r0\\n\\ -\\tmov\\tr15, r1\\n\\ -\\tmov\\t#(0f-1f), r15\\n\\ -0:\\tmov.\\t@%1, %0\\n\\ -\\tand\\t%2, %0\\n\\ -\\tnot\\t%0, %0\\n\\ -\\tmov.\\t%0, @%1\\n\\ -\\t.align\\t2\\n\\ -1:\\tmov\tr1, r15\"; -}" + return "mova 1f,r0" "\n" + " .align 2" "\n" + " mov r15,r1" "\n" + " mov #(0f-1f),r15" "\n" + "0: mov. @%1,%0" "\n" + " and %2,%0" "\n" + " not %0,%0" "\n" + " mov. %0,@%1" "\n" + "1: mov r1,r15"; +} [(set_attr "length" "18")])