Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp191840pxj; Tue, 18 May 2021 00:49:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwhAL3yrUo34CTucHZIHyVf/hQU+WCxvKLy866soG3aMeJQ8keeADrN/5XqleuAUzTdSvwa X-Received: by 2002:a17:906:fa83:: with SMTP id lt3mr4635053ejb.261.1621324143816; Tue, 18 May 2021 00:49:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1621324143; cv=none; d=google.com; s=arc-20160816; b=gWB1GvTNGJdYMKyOKJQSxnvkx40vdunq16t5qPnzAsnGiYf3B22zZkvfckCJDkFHNi UpHxHD9nzYkAuAv2Cd32mloKMBW0p5z+DtiF0SwUKPnMk/5l/SrOWbMbvUUcivLuqeV7 vf3MOvNlXQPqoBrb8Aw2MmdRSXHh2jRXa+/BzxuwXWbWrb1NSjDQIH6iS+lbpETdSDdK rUjQlkSdIKEvJs7Oc9FPJszMg5uW1TdJLOxejEe7XyK/nRjqdUBRexWpYJbSjh/aEZK7 p5bqQjvig4rRWOO1aVW4X1w6f2lZE/eB0MSOc30CT4S5sC9zsoyg5YC3EBgJRabIc3a1 ouEg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=x3AziD9tuVobITDsIw2OgdDQA1rnRQ542H++uF8lbDY=; b=kdDtbY3P2VZkju0rN/3osc3JdMF9LyDAVFq3nQOPrvYUb6V+vQf/CQHPpDnxcw9rJR 3bVApbblqVvCvv/WV9fG0tihK+O8z9Yh1Z+XzUQ9OEgl6Wj9aPGSvqfT9m/+CSOXqK68 sKIYqI6LqryPyJVp0LUid6nl64ZTjWlcmIAMe4u3e3O98H1Tm9vIUbF6pzesDmi7Dhqd aXTzqxIhIhGmEqJJPtEJzkCTK5566MZKKz6x284/sCZze0FCT/WFhH4pgfFtX9vKiCY/ fmuSBDWB14BpvWAwlTH+1UXz1kPK9EWe2JLHLj/39Vv5sVfY+DSs/JkOrgKEtp8R168h SS9g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=GdWitZZo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n17si15575606ejb.145.2021.05.18.00.48.41; Tue, 18 May 2021 00:49:03 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=GdWitZZo; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241015AbhEQO6C (ORCPT + 99 others); Mon, 17 May 2021 10:58:02 -0400 Received: from mail.kernel.org ([198.145.29.99]:39052 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241909AbhEQOs2 (ORCPT ); Mon, 17 May 2021 10:48:28 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id ACA4A6117A; Mon, 17 May 2021 14:22:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1621261345; bh=WQfgM7ZoBlcn0q0ZndU0b98p6G+CR1wQVtqSdzHtEnI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=GdWitZZoyoLCyrPsseXuScLIX+n5WKxwHivSY0DpA446d+0OUBL5MyyWpQrqJbmlN l1lpuZc4s0J1CPMNa72Yc2GU2FlWGXYKjQKwTejUPlncDOb9GXssS1ME3z+rBJyNX+ nAgV/11+CIvjFc3rkDc4BCf6OLSa4+6Peh+tqx74= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Huacai Chen , "Maciej W. Rozycki" , Thomas Bogendoerfer Subject: [PATCH 5.12 336/363] MIPS: Reinstate platform `__div64_32 handler Date: Mon, 17 May 2021 16:03:22 +0200 Message-Id: <20210517140313.969937927@linuxfoundation.org> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210517140302.508966430@linuxfoundation.org> References: <20210517140302.508966430@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Maciej W. Rozycki commit c49f71f60754acbff37505e1d16ca796bf8a8140 upstream. Our current MIPS platform `__div64_32' handler is inactive, because it is incorrectly only enabled for 64-bit configurations, for which generic `do_div' code does not call it anyway. The handler is not suitable for being called from there though as it only calculates 32 bits of the quotient under the assumption the 64-bit divident has been suitably reduced. Code for such reduction used to be there, however it has been incorrectly removed with commit c21004cd5b4c ("MIPS: Rewrite to work with gcc 4.4.0."), which should have only updated an obsoleted constraint for an inline asm involving $hi and $lo register outputs, while possibly wiring the original MIPS variant of the `do_div' macro as `__div64_32' handler for the generic `do_div' implementation Correct the handler as follows then: - Revert most of the commit referred, however retaining the current formatting, except for the final two instructions of the inline asm sequence, which the original commit missed. Omit the original 64-bit parts though. - Rename the original `do_div' macro to `__div64_32'. Use the combined `x' constraint referring to the MD accumulator as a whole, replacing the original individual `h' and `l' constraints used for $hi and $lo registers respectively, of which `h' has been obsoleted with GCC 4.4. Update surrounding code accordingly. We have since removed support for GCC versions before 4.9, so no need for a special arrangement here; GCC has supported the `x' constraint since forever anyway, or at least going back to 1991. - Rename the `__base' local variable in `__div64_32' to `__radix' to avoid a conflict with a local variable in `do_div'. - Actually enable this code for 32-bit rather than 64-bit configurations by qualifying it with BITS_PER_LONG being 32 instead of 64. Include for this macro rather than as we don't need anything else. - Finally include last rather than first. This has passed correctness verification with test_div64 and reduced the module's average execution time down to 1.0668s and 0.2629s from 2.1529s and 0.5647s respectively for an R3400 CPU @40MHz and a 5Kc CPU @160MHz. For a reference 64-bit `do_div' code where we have the DDIVU instruction available to do the whole calculation right away averages at 0.0660s for the latter CPU. Fixes: c21004cd5b4c ("MIPS: Rewrite to work with gcc 4.4.0.") Reported-by: Huacai Chen Signed-off-by: Maciej W. Rozycki Cc: stable@vger.kernel.org # v2.6.30+ Signed-off-by: Thomas Bogendoerfer Signed-off-by: Greg Kroah-Hartman --- arch/mips/include/asm/div64.h | 57 ++++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 16 deletions(-) --- a/arch/mips/include/asm/div64.h +++ b/arch/mips/include/asm/div64.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2000, 2004 Maciej W. Rozycki + * Copyright (C) 2000, 2004, 2021 Maciej W. Rozycki * Copyright (C) 2003, 07 Ralf Baechle (ralf@linux-mips.org) * * This file is subject to the terms and conditions of the GNU General Public @@ -9,25 +9,18 @@ #ifndef __ASM_DIV64_H #define __ASM_DIV64_H -#include - -#if BITS_PER_LONG == 64 +#include -#include +#if BITS_PER_LONG == 32 /* * No traps on overflows for any of these... */ -#define __div64_32(n, base) \ -({ \ +#define do_div64_32(res, high, low, base) ({ \ unsigned long __cf, __tmp, __tmp2, __i; \ unsigned long __quot32, __mod32; \ - unsigned long __high, __low; \ - unsigned long long __n; \ \ - __high = *__n >> 32; \ - __low = __n; \ __asm__( \ " .set push \n" \ " .set noat \n" \ @@ -51,18 +44,50 @@ " subu %0, %0, %z6 \n" \ " addiu %2, %2, 1 \n" \ "3: \n" \ - " bnez %4, 0b\n\t" \ - " srl %5, %1, 0x1f\n\t" \ + " bnez %4, 0b \n" \ + " srl %5, %1, 0x1f \n" \ " .set pop" \ : "=&r" (__mod32), "=&r" (__tmp), \ "=&r" (__quot32), "=&r" (__cf), \ "=&r" (__i), "=&r" (__tmp2) \ - : "Jr" (base), "0" (__high), "1" (__low)); \ + : "Jr" (base), "0" (high), "1" (low)); \ \ - (__n) = __quot32; \ + (res) = __quot32; \ __mod32; \ }) -#endif /* BITS_PER_LONG == 64 */ +#define __div64_32(n, base) ({ \ + unsigned long __upper, __low, __high, __radix; \ + unsigned long long __modquot; \ + unsigned long long __quot; \ + unsigned long long __div; \ + unsigned long __mod; \ + \ + __div = (*n); \ + __radix = (base); \ + \ + __high = __div >> 32; \ + __low = __div; \ + __upper = __high; \ + \ + if (__high) { \ + __asm__("divu $0, %z1, %z2" \ + : "=x" (__modquot) \ + : "Jr" (__high), "Jr" (__radix)); \ + __upper = __modquot >> 32; \ + __high = __modquot; \ + } \ + \ + __mod = do_div64_32(__low, __upper, __low, __radix); \ + \ + __quot = __high; \ + __quot = __quot << 32 | __low; \ + (*n) = __quot; \ + __mod; \ +}) + +#endif /* BITS_PER_LONG == 32 */ + +#include #endif /* __ASM_DIV64_H */