From patchwork Tue Aug 4 14:59:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Stubbs X-Patchwork-Id: 1340895 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BLdFT6L0Bz9sTd for ; Wed, 5 Aug 2020 00:59:24 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 905A3384242E; Tue, 4 Aug 2020 14:59:22 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from esa4.mentor.iphmx.com (esa4.mentor.iphmx.com [68.232.137.252]) by sourceware.org (Postfix) with ESMTPS id 102D83861039 for ; Tue, 4 Aug 2020 14:59:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 102D83861039 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=codesourcery.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=Andrew_Stubbs@mentor.com IronPort-SDR: qlZNuiJRF7yp0OI4oACn47k+CdTgLtrqcsZNFNvyzg4rBViV+u5dEapso+T8cw/D3/IQt3iC70 t6/P3I80IzklA9NR8/obiX0DNOyMrM34Wa9UJW51YymZFfE6nZZcWXEYaeo9WaSMQ98G4WABfH ryMMVwopBUHVdhbDRbRlDAOxUHapMV2oQkQkW3hlQurZnVji1TJkS1pyaz4J+qSOPtbLdtsVbz 0pWDT5MCqOthKaUokL6HQF9C3saEEJAa6JXDnqS4XjGgE5PUEfUl169lIlrf2ECUjb/FxrtQTn BK0= X-IronPort-AV: E=Sophos;i="5.75,434,1589270400"; d="scan'208";a="51714612" Received: from orw-gwy-02-in.mentorg.com ([192.94.38.167]) by esa4.mentor.iphmx.com with ESMTP; 04 Aug 2020 06:59:18 -0800 IronPort-SDR: +JT9TJAD2tCHvHc+CGZxL77tnDGngQQ8yOZObLF8FoGQt7uSmzGP/x3FILdLHj03qlhTaJ28B6 vYz6HKMcIkTvA2/jefApPu7A6oxVVvZYOThXyqQJLhWk9ULirhk5pq+IcrX6fybcxQog8/MedI qMebnLgB7saFd+d4QENUAsG5GgYfjb05qFPcVkFiHS4w+Giie51v/7EXGRotkppl/0nxEs0bMP k90/1qZ3X2Jo4veINcJkxTunpoOJLUQ51owGxQRgOM/SOTIoaY0Lcj2P6yg3dAyhNTp3avtjJ4 nsA= From: Andrew Stubbs Subject: [committed] amdgcn: TImode shifts To: "gcc-patches@gcc.gnu.org" Message-ID: <9085216e-4762-1e27-58ac-7a6adf131da3@codesourcery.com> Date: Tue, 4 Aug 2020 15:59:13 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.10.0 MIME-Version: 1.0 Content-Language: en-GB X-Originating-IP: [137.202.0.90] X-ClientProxiedBy: SVR-IES-MBX-04.mgc.mentorg.com (139.181.222.4) To SVR-IES-MBX-03.mgc.mentorg.com (139.181.222.3) X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" This patch implements scalar TImode shifts using hardware DImode shifts. The middle-end cannot synthesize these because BITS_PER_WORD is 32, on this architecture, meaning it would try to use SImode shifts, and only double-word shifts are implemented. This fixes a large number of test failures, caused by the need to enable TImode to support libgomp. TImode multiply and divide remain unimplemented. Andrew amdgcn: TImode shifts Implement TImode shifts in the backend. The middle-end support that does it for other architectures doesn't work for GCN because BITS_PER_WORD==32, meaning that TImode is quad-word, not double-word. gcc/ChangeLog: * config/gcn/gcn.md ("ti3"): New. diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md index 8cfb3a85d25..ed98d2d2706 100644 --- a/gcc/config/gcn/gcn.md +++ b/gcc/config/gcn/gcn.md @@ -1538,6 +1538,111 @@ (define_insn "di3" [(set_attr "type" "sop2,sop2,vop2") (set_attr "length" "8")]) +;; }}} +;; {{{ ALU: generic 128-bit binop + +; TImode shifts can't be synthesized by the middle-end +(define_expand "ti3" + [(set (match_operand:TI 0 "register_operand") + (vec_and_scalar_nocom:TI + (match_operand:TI 1 "gcn_alu_operand") + (match_operand:SI 2 "gcn_alu_operand")))] + "" + { + rtx dest = operands[0]; + rtx src = operands[1]; + rtx shift = operands[2]; + + enum {ashr, lshr, ashl} shiftop = ; + rtx (*inverse_shift_fn) (rtx, rtx, rtx) + = (shiftop == ashl ? gen_lshrdi3 : gen_ashldi3); + rtx (*logical_shift_fn) (rtx, rtx, rtx) + = (shiftop == ashl ? gen_ashldi3 : gen_lshrdi3); + + /* We shift "from" one subreg "to" the other, according to shiftop. */ + int from = (shiftop == ashl ? 0 : 8); + int to = (shiftop == ashl ? 8 : 0); + rtx destfrom = simplify_gen_subreg (DImode, dest, TImode, from); + rtx destto = simplify_gen_subreg (DImode, dest, TImode, to); + rtx srcfrom = simplify_gen_subreg (DImode, src, TImode, from); + rtx srcto = simplify_gen_subreg (DImode, src, TImode, to); + + int shiftval = (CONST_INT_P (shift) ? INTVAL (shift) : -1); + enum {RUNTIME, ZERO, SMALL, LARGE} shiftcomparison + = (!CONST_INT_P (shift) ? RUNTIME + : shiftval == 0 ? ZERO + : shiftval < 64 ? SMALL + : LARGE); + + rtx large_label, zero_label, exit_label; + + if (shiftcomparison == RUNTIME) + { + zero_label = gen_label_rtx (); + large_label = gen_label_rtx (); + exit_label = gen_label_rtx (); + + rtx cond = gen_rtx_EQ (VOIDmode, shift, const0_rtx); + emit_insn (gen_cbranchsi4 (cond, shift, const0_rtx, zero_label)); + + rtx sixtyfour = GEN_INT (64); + cond = gen_rtx_GE (VOIDmode, shift, sixtyfour); + emit_insn (gen_cbranchsi4 (cond, shift, sixtyfour, large_label)); + } + + if (shiftcomparison == SMALL || shiftcomparison == RUNTIME) + { + /* Shift both parts by the same amount, then patch in the bits that + cross the boundary. + This does *not* work for zero-length shifts. */ + rtx tmpto1 = gen_reg_rtx (DImode); + rtx tmpto2 = gen_reg_rtx (DImode); + emit_insn (gen_di3 (destfrom, srcfrom, shift)); + emit_insn (logical_shift_fn (tmpto1, srcto, shift)); + rtx lessershiftval = gen_reg_rtx (SImode); + emit_insn (gen_subsi3 (lessershiftval, GEN_INT (64), shift)); + emit_insn (inverse_shift_fn (tmpto2, srcfrom, lessershiftval)); + emit_insn (gen_iordi3 (destto, tmpto1, tmpto2)); + } + + if (shiftcomparison == RUNTIME) + { + emit_jump_insn (gen_jump (exit_label)); + emit_barrier (); + + emit_label (zero_label); + } + + if (shiftcomparison == ZERO || shiftcomparison == RUNTIME) + emit_move_insn (dest, src); + + if (shiftcomparison == RUNTIME) + { + emit_jump_insn (gen_jump (exit_label)); + emit_barrier (); + + emit_label (large_label); + } + + if (shiftcomparison == LARGE || shiftcomparison == RUNTIME) + { + /* Do the shift within one part, and set the other part appropriately. + Shifts of 128+ bits are an error. */ + rtx lessershiftval = gen_reg_rtx (SImode); + emit_insn (gen_subsi3 (lessershiftval, shift, GEN_INT (64))); + emit_insn (gen_di3 (destto, srcfrom, lessershiftval)); + if (shiftop == ashr) + emit_insn (gen_ashrdi3 (destfrom, srcfrom, GEN_INT (63))); + else + emit_move_insn (destfrom, const0_rtx); + } + + if (shiftcomparison == RUNTIME) + emit_label (exit_label); + + DONE; + }) + ;; }}} ;; {{{ Atomics