From patchwork Mon Nov 18 20:07:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ulrich Weigand X-Patchwork-Id: 292184 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 843C22C00C2 for ; Tue, 19 Nov 2013 07:08:00 +1100 (EST) 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:to:date:from:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=DeOvqb6pIdusVor0 XP+o/cu6lXAoFW32c9qCCOCUmha+gzzvvm2tA66ifw+zb4ffNEFtBJODAO5aPaD3 3J73lRDQWEC1wFMWI5cGiSRwAUBKRguKDtSV8J5MhSPL+r2QVtGQ/Vq/BvYdW/FQ 27d/Ngl43m9YhGBiq3kGQTkv9h8= 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:to:date:from:mime-version:content-type :content-transfer-encoding; s=default; bh=evr59+Xn2ze9vzfrROJqsL MC7yk=; b=SPMMXn9wbz3vWzWDVE9f8rvUrVpTnCE8VgCKVWFYkNfBRdWWOS4yIh l4r1bv0DVUeT6Wy0JCV5D9A4es6XCDhDvCJiEmUFMZuA/SBpYzhhHY11qlsQLt6t ixDabaTVRyYdoPnMcAA6Jg6OLptBYot6zypwAY+dYLxkpvOAO6AjQ= Received: (qmail 23726 invoked by alias); 18 Nov 2013 20:07:49 -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 23715 invoked by uid 89); 18 Nov 2013 20:07:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.0 required=5.0 tests=AWL, BAYES_50, MSGID_FROM_MTA_HEADER, RDNS_NONE, SPF_PASS autolearn=no version=3.3.2 X-HELO: e06smtp15.uk.ibm.com Received: from Unknown (HELO e06smtp15.uk.ibm.com) (195.75.94.111) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Mon, 18 Nov 2013 20:07:48 +0000 Received: from /spool/local by e06smtp15.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 18 Nov 2013 20:07:38 -0000 Received: from d06dlp02.portsmouth.uk.ibm.com (9.149.20.14) by e06smtp15.uk.ibm.com (192.168.101.145) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 18 Nov 2013 20:07:36 -0000 Received: from b06cxnps4076.portsmouth.uk.ibm.com (d06relay13.portsmouth.uk.ibm.com [9.149.109.198]) by d06dlp02.portsmouth.uk.ibm.com (Postfix) with ESMTP id 95BA12190023 for ; Mon, 18 Nov 2013 20:07:35 +0000 (GMT) Received: from d06av02.portsmouth.uk.ibm.com (d06av02.portsmouth.uk.ibm.com [9.149.37.228]) by b06cxnps4076.portsmouth.uk.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id rAIK7NeC61669404 for ; Mon, 18 Nov 2013 20:07:23 GMT Received: from d06av02.portsmouth.uk.ibm.com (localhost [127.0.0.1]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id rAIK7ZYL024795 for ; Mon, 18 Nov 2013 13:07:35 -0700 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d06av02.portsmouth.uk.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with SMTP id rAIK7Xhx024773; Mon, 18 Nov 2013 13:07:33 -0700 Message-Id: <201311182007.rAIK7Xhx024773@d06av02.portsmouth.uk.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Mon, 18 Nov 2013 21:07:33 +0100 Subject: [PATCH, rs6000] Fix order of TDmode in FPRs in little-endian mode To: gcc-patches@gcc.gnu.org, dje.gcc@gmail.com Date: Mon, 18 Nov 2013 21:07:33 +0100 (CET) From: "Ulrich Weigand" MIME-Version: 1.0 X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 13111820-0342-0000-0000-000006E62DC2 Hello, when loading a TDmode value into floating-point registers, they need to go into a register pair with the even register holding the most significant word and the odd register holding the least significant word, because this is what the instruction set expects. This hold for both big-endian and little-endian mode. However, in little-endian mode, the usual subreg logic will place the least significant word into the lower-numbered register, which is wrong. This causes all _Decimal128 tests to fail when using a --with-cpu that includes DFP instructions. To fix this, the patch below: - disables subregs of TDmode in FPRs in little-endian mode in rs6000_cannot_change_mode_class, to ensure nobody is using the generic subreg logic for such values, and - changes rs6000_split_multireg_move to avoid using simplify_gen_subreg on such values, but instead create the correct register numbers "by hand" Note that this patch implies an ABI change on little-endian for passing _Decimal128 values in register pairs. Also note that this patch does not change how TDmode values are loaded into GPRs: on little-endian, this means we do get the usual LE subreg order there (least significant word in lowest-numbered register). This does still seem the right thing to do, because there are no instructions that operate on DFP values in GPRs, and because this allows us to keep using subregs on GPRs in that case, and it allows moving TDmode between memory and GPRs (e.g. for vararg arguments) in the usual way. Tested on powerpc64le-linux, fixes all remaining DFP-related test suite failures. OK for mainline? Bye, Ulrich ChangeLog: * config/rs6000/rs6000.c (rs6000_cannot_change_mode_class): Do not allow subregs of TDmode in FPRs of smaller size in little-endian. (rs6000_split_multireg_move): When splitting an access to TDmode in FPRs, do not use simplify_gen_subreg. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 204948) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -16664,6 +16664,13 @@ if (TARGET_IEEEQUAD && (to == TFmode || from == TFmode)) return true; + /* TDmode in floating-mode registers must always go into a register + pair with the most significant word in the even-numbered register + to match ISA requirements. In little-endian mode, this does not + match subreg numbering, so we cannot allow subregs. */ + if (!BYTES_BIG_ENDIAN && (to == TDmode || from == TDmode)) + return true; + if (from_size < 8 || to_size < 8) return true; @@ -19606,6 +19613,39 @@ gcc_assert (reg_mode_size * nregs == GET_MODE_SIZE (mode)); + /* TDmode residing in FP registers is special, since the ISA requires that + the lower-numbered word of a register pair is always the most significant + word, even in little-endian mode. This does not match the usual subreg + semantics, so we cannnot use simplify_gen_subreg in those cases. Access + the appropriate constituent registers "by hand" in little-endian mode. + + Note we do not need to check for destructive overlap here since TDmode + can only reside in even/odd register pairs. */ + if (FP_REGNO_P (reg) && DECIMAL_FLOAT_MODE_P (mode) && !BYTES_BIG_ENDIAN) + { + rtx p_src, p_dst; + int i; + + for (i = 0; i < nregs; i++) + { + if (REG_P (src) && FP_REGNO_P (REGNO (src))) + p_src = gen_rtx_REG (reg_mode, REGNO (src) + nregs - 1 - i); + else + p_src = simplify_gen_subreg (reg_mode, src, mode, + i * reg_mode_size); + + if (REG_P (dst) && FP_REGNO_P (REGNO (dst))) + p_dst = gen_rtx_REG (reg_mode, REGNO (dst) + nregs - 1 - i); + else + p_dst = simplify_gen_subreg (reg_mode, dst, mode, + i * reg_mode_size); + + emit_insn (gen_rtx_SET (VOIDmode, p_dst, p_src)); + } + + return; + } + if (REG_P (src) && REG_P (dst) && (REGNO (src) < REGNO (dst))) { /* Move register range backwards, if we might have destructive