From: Nicolas Pitre <nico@fluxnic.net>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Antony Yu <swpenim@gmail.com>,
Nick Desaulniers <ndesaulniers@google.com>,
Russell King <linux@armlinux.org.uk>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
clang-built-linux <clang-built-linux@googlegroups.com>,
Nathan Chancellor <natechancellor@gmail.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [RESEND,PATCH] ARM: fix __div64_32() error when compiling with clang
Date: Mon, 30 Nov 2020 12:52:25 -0500 (EST) [thread overview]
Message-ID: <85p0oop-5pq-p6o-7560-297sn1np3os@syhkavp.arg> (raw)
In-Reply-To: <CAMj1kXGuHw+p5=YPrVwaHjp5hQ9uxsp7hbA0Vk-ppZ3_qHDVrA@mail.gmail.com>
On Mon, 30 Nov 2020, Ard Biesheuvel wrote:
> On Mon, 30 Nov 2020 at 16:51, Nicolas Pitre <nico@fluxnic.net> wrote:
>
> > Here's my version of the fix which should be correct. Warning: this
> > is completely untested, but should in theory produce the same code on
> > modern gcc.
> >
> > diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
> > index 898e9c78a7..595e538f5b 100644
> > --- a/arch/arm/include/asm/div64.h
> > +++ b/arch/arm/include/asm/div64.h
> > @@ -21,29 +21,20 @@
> > * assembly implementation with completely non standard calling convention
> > * for arguments and results (beware).
> > */
> > -
> > -#ifdef __ARMEB__
> > -#define __xh "r0"
> > -#define __xl "r1"
> > -#else
> > -#define __xl "r0"
> > -#define __xh "r1"
> > -#endif
> > -
> > static inline uint32_t __div64_32(uint64_t *n, uint32_t base)
> > {
> > register unsigned int __base asm("r4") = base;
> > register unsigned long long __n asm("r0") = *n;
> > register unsigned long long __res asm("r2");
> > - register unsigned int __rem asm(__xh);
> > - asm( __asmeq("%0", __xh)
> > + unsigned int __rem;
> > + asm( __asmeq("%0", "r0")
> > __asmeq("%1", "r2")
> > - __asmeq("%2", "r0")
> > - __asmeq("%3", "r4")
> > + __asmeq("%2", "r4")
> > "bl __do_div64"
> > - : "=r" (__rem), "=r" (__res)
> > - : "r" (__n), "r" (__base)
> > + : "+r" (__n), "=r" (__res)
> > + : "r" (__base)
> > : "ip", "lr", "cc");
> > + __rem = __n >> 32;
>
> This treats {r0, r1} as a {low, high} pair, regardless of endianness,
> and so it puts the value of r0 into r1. Doesn't that mean the shift
> should only be done on little endian?
Not quite. r0-r1 = low-high is for little endian. Then "__n >> 32" is
actually translated into "mov r0, r1" to move it into __rem and returned
through r0.
On big endial it is r0-r1 = high-low. Here "__n >> 32" picks r0 and
moves it to __rem which is returned through r0 so no extra instruction
needed.
Of course the function is inlined so r0 can be anything, or optimized
away if__rem is not used.
Nicolas
WARNING: multiple messages have this Message-ID (diff)
From: Nicolas Pitre <nico@fluxnic.net>
To: Ard Biesheuvel <ardb@kernel.org>
Cc: Antony Yu <swpenim@gmail.com>,
Nick Desaulniers <ndesaulniers@google.com>,
Russell King <linux@armlinux.org.uk>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
clang-built-linux <clang-built-linux@googlegroups.com>,
Nathan Chancellor <natechancellor@gmail.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>
Subject: Re: [RESEND,PATCH] ARM: fix __div64_32() error when compiling with clang
Date: Mon, 30 Nov 2020 12:52:25 -0500 (EST) [thread overview]
Message-ID: <85p0oop-5pq-p6o-7560-297sn1np3os@syhkavp.arg> (raw)
In-Reply-To: <CAMj1kXGuHw+p5=YPrVwaHjp5hQ9uxsp7hbA0Vk-ppZ3_qHDVrA@mail.gmail.com>
On Mon, 30 Nov 2020, Ard Biesheuvel wrote:
> On Mon, 30 Nov 2020 at 16:51, Nicolas Pitre <nico@fluxnic.net> wrote:
>
> > Here's my version of the fix which should be correct. Warning: this
> > is completely untested, but should in theory produce the same code on
> > modern gcc.
> >
> > diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
> > index 898e9c78a7..595e538f5b 100644
> > --- a/arch/arm/include/asm/div64.h
> > +++ b/arch/arm/include/asm/div64.h
> > @@ -21,29 +21,20 @@
> > * assembly implementation with completely non standard calling convention
> > * for arguments and results (beware).
> > */
> > -
> > -#ifdef __ARMEB__
> > -#define __xh "r0"
> > -#define __xl "r1"
> > -#else
> > -#define __xl "r0"
> > -#define __xh "r1"
> > -#endif
> > -
> > static inline uint32_t __div64_32(uint64_t *n, uint32_t base)
> > {
> > register unsigned int __base asm("r4") = base;
> > register unsigned long long __n asm("r0") = *n;
> > register unsigned long long __res asm("r2");
> > - register unsigned int __rem asm(__xh);
> > - asm( __asmeq("%0", __xh)
> > + unsigned int __rem;
> > + asm( __asmeq("%0", "r0")
> > __asmeq("%1", "r2")
> > - __asmeq("%2", "r0")
> > - __asmeq("%3", "r4")
> > + __asmeq("%2", "r4")
> > "bl __do_div64"
> > - : "=r" (__rem), "=r" (__res)
> > - : "r" (__n), "r" (__base)
> > + : "+r" (__n), "=r" (__res)
> > + : "r" (__base)
> > : "ip", "lr", "cc");
> > + __rem = __n >> 32;
>
> This treats {r0, r1} as a {low, high} pair, regardless of endianness,
> and so it puts the value of r0 into r1. Doesn't that mean the shift
> should only be done on little endian?
Not quite. r0-r1 = low-high is for little endian. Then "__n >> 32" is
actually translated into "mov r0, r1" to move it into __rem and returned
through r0.
On big endial it is r0-r1 = high-low. Here "__n >> 32" picks r0 and
moves it to __rem which is returned through r0 so no extra instruction
needed.
Of course the function is inlined so r0 can be anything, or optimized
away if__rem is not used.
Nicolas
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-11-30 17:53 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-23 7:36 [RESEND,PATCH] ARM: fix __div64_32() error when compiling with clang Antony Yu
2020-11-23 7:36 ` Antony Yu
2020-11-23 18:16 ` Nathan Chancellor
2020-11-23 18:16 ` Nathan Chancellor
2020-11-24 7:42 ` Antony Yu
2020-11-24 10:14 ` Antony Yu
2020-11-24 10:14 ` [RESEND, PATCH] " Antony Yu
2020-11-24 21:06 ` [RESEND,PATCH] " Nick Desaulniers
2020-11-24 21:06 ` [RESEND, PATCH] " Nick Desaulniers
2020-11-30 8:20 ` [PATCH v2] " Antony Yu
2020-11-30 8:20 ` Antony Yu
2020-11-24 23:16 ` [RESEND,PATCH] " kernel test robot
2020-11-24 23:16 ` [RESEND, PATCH] " kernel test robot
2020-11-24 23:16 ` [RESEND,PATCH] " kernel test robot
2020-11-30 10:11 ` Ard Biesheuvel
2020-11-30 10:11 ` [RESEND, PATCH] " Ard Biesheuvel
2020-11-30 10:12 ` [RESEND,PATCH] " Ard Biesheuvel
2020-11-30 10:12 ` [RESEND, PATCH] " Ard Biesheuvel
2020-11-30 10:21 ` [RESEND,PATCH] " Russell King - ARM Linux admin
2020-11-30 10:21 ` Russell King - ARM Linux admin
2020-11-30 10:40 ` Ard Biesheuvel
2020-11-30 10:40 ` [RESEND, PATCH] " Ard Biesheuvel
2020-11-30 13:58 ` [RESEND,PATCH] " David Laight
2020-11-30 13:58 ` David Laight
2020-11-30 14:18 ` Russell King - ARM Linux admin
2020-11-30 14:18 ` Russell King - ARM Linux admin
2020-11-30 15:50 ` Nicolas Pitre
2020-11-30 15:50 ` Nicolas Pitre
2020-11-30 17:18 ` Ard Biesheuvel
2020-11-30 17:18 ` [RESEND, PATCH] " Ard Biesheuvel
2020-11-30 17:52 ` Nicolas Pitre [this message]
2020-11-30 17:52 ` [RESEND,PATCH] " Nicolas Pitre
2020-11-30 18:08 ` Ard Biesheuvel
2020-11-30 18:08 ` [RESEND, PATCH] " Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=85p0oop-5pq-p6o-7560-297sn1np3os@syhkavp.arg \
--to=nico@fluxnic.net \
--cc=ardb@kernel.org \
--cc=clang-built-linux@googlegroups.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=natechancellor@gmail.com \
--cc=ndesaulniers@google.com \
--cc=swpenim@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.