Message ID | 20201107001056.225807-1-jiancai@google.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] Make iwmmxt.S support Clang's integrated assembler | expand |
On Sat, 7 Nov 2020 at 01:11, Jian Cai <jiancai@google.com> wrote: > > This patch replaces 6 IWMMXT instructions Clang's integrated assembler > does not support in iwmmxt.S using macros, while making sure GNU > assembler still emit the same instructions. This should be easier than > providing full IWMMXT support in Clang. > > "Intel Wireless MMX Technology - Developer Guide - August, 2002" should > be referenced for the encoding schemes of these extensions. > > Link: https://github.com/ClangBuiltLinux/linux/issues/975 > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com> > Suggested-by: Ard Biesheuvel <ardb@kernel.org> > Signed-off-by: Jian Cai <jiancai@google.com> Please make sure you test this carefully on BE32, as the instruction byte order used by .inst is LE IIRC > --- > arch/arm/kernel/iwmmxt.S | 89 ++++++++++++++++++++-------------------- > arch/arm/kernel/iwmmxt.h | 47 +++++++++++++++++++++ > 2 files changed, 92 insertions(+), 44 deletions(-) > create mode 100644 arch/arm/kernel/iwmmxt.h > > diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S > index 0dcae787b004..d2b4ac06e4ed 100644 > --- a/arch/arm/kernel/iwmmxt.S > +++ b/arch/arm/kernel/iwmmxt.S > @@ -16,6 +16,7 @@ > #include <asm/thread_info.h> > #include <asm/asm-offsets.h> > #include <asm/assembler.h> > +#include "iwmmxt.h" > > #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) > #define PJ4(code...) code > @@ -113,33 +114,33 @@ concan_save: > > concan_dump: > > - wstrw wCSSF, [r1, #MMX_WCSSF] > - wstrw wCASF, [r1, #MMX_WCASF] > - wstrw wCGR0, [r1, #MMX_WCGR0] > - wstrw wCGR1, [r1, #MMX_WCGR1] > - wstrw wCGR2, [r1, #MMX_WCGR2] > - wstrw wCGR3, [r1, #MMX_WCGR3] > + wstrw wCSSF, r1, MMX_WCSSF > + wstrw wCASF, r1, MMX_WCASF > + wstrw wCGR0, r1, MMX_WCGR0 > + wstrw wCGR1, r1, MMX_WCGR1 > + wstrw wCGR2, r1, MMX_WCGR2 > + wstrw wCGR3, r1, MMX_WCGR3 > > 1: @ MUP? wRn > tst r2, #0x2 > beq 2f > > - wstrd wR0, [r1, #MMX_WR0] > - wstrd wR1, [r1, #MMX_WR1] > - wstrd wR2, [r1, #MMX_WR2] > - wstrd wR3, [r1, #MMX_WR3] > - wstrd wR4, [r1, #MMX_WR4] > - wstrd wR5, [r1, #MMX_WR5] > - wstrd wR6, [r1, #MMX_WR6] > - wstrd wR7, [r1, #MMX_WR7] > - wstrd wR8, [r1, #MMX_WR8] > - wstrd wR9, [r1, #MMX_WR9] > - wstrd wR10, [r1, #MMX_WR10] > - wstrd wR11, [r1, #MMX_WR11] > - wstrd wR12, [r1, #MMX_WR12] > - wstrd wR13, [r1, #MMX_WR13] > - wstrd wR14, [r1, #MMX_WR14] > - wstrd wR15, [r1, #MMX_WR15] > + wstrd wR0, r1, MMX_WR0 > + wstrd wR1, r1, MMX_WR1 > + wstrd wR2, r1, MMX_WR2 > + wstrd wR3, r1, MMX_WR3 > + wstrd wR4, r1, MMX_WR4 > + wstrd wR5, r1, MMX_WR5 > + wstrd wR6, r1, MMX_WR6 > + wstrd wR7, r1, MMX_WR7 > + wstrd wR8, r1, MMX_WR8 > + wstrd wR9, r1, MMX_WR9 > + wstrd wR10, r1, MMX_WR10 > + wstrd wR11, r1, MMX_WR11 > + wstrd wR12, r1, MMX_WR12 > + wstrd wR13, r1, MMX_WR13 > + wstrd wR14, r1, MMX_WR14 > + wstrd wR15, r1, MMX_WR15 > > 2: teq r0, #0 @ anything to load? > reteq lr @ if not, return > @@ -147,30 +148,30 @@ concan_dump: > concan_load: > > @ Load wRn > - wldrd wR0, [r0, #MMX_WR0] > - wldrd wR1, [r0, #MMX_WR1] > - wldrd wR2, [r0, #MMX_WR2] > - wldrd wR3, [r0, #MMX_WR3] > - wldrd wR4, [r0, #MMX_WR4] > - wldrd wR5, [r0, #MMX_WR5] > - wldrd wR6, [r0, #MMX_WR6] > - wldrd wR7, [r0, #MMX_WR7] > - wldrd wR8, [r0, #MMX_WR8] > - wldrd wR9, [r0, #MMX_WR9] > - wldrd wR10, [r0, #MMX_WR10] > - wldrd wR11, [r0, #MMX_WR11] > - wldrd wR12, [r0, #MMX_WR12] > - wldrd wR13, [r0, #MMX_WR13] > - wldrd wR14, [r0, #MMX_WR14] > - wldrd wR15, [r0, #MMX_WR15] > + wldrd wR0, r0, MMX_WR0 > + wldrd wR1, r0, MMX_WR1 > + wldrd wR2, r0, MMX_WR2 > + wldrd wR3, r0, MMX_WR3 > + wldrd wR4, r0, MMX_WR4 > + wldrd wR5, r0, MMX_WR5 > + wldrd wR6, r0, MMX_WR6 > + wldrd wR7, r0, MMX_WR7 > + wldrd wR8, r0, MMX_WR8 > + wldrd wR9, r0, MMX_WR9 > + wldrd wR10, r0, MMX_WR10 > + wldrd wR11, r0, MMX_WR11 > + wldrd wR12, r0, MMX_WR12 > + wldrd wR13, r0, MMX_WR13 > + wldrd wR14, r0, MMX_WR14 > + wldrd wR15, r0, MMX_WR15 > > @ Load wCx > - wldrw wCSSF, [r0, #MMX_WCSSF] > - wldrw wCASF, [r0, #MMX_WCASF] > - wldrw wCGR0, [r0, #MMX_WCGR0] > - wldrw wCGR1, [r0, #MMX_WCGR1] > - wldrw wCGR2, [r0, #MMX_WCGR2] > - wldrw wCGR3, [r0, #MMX_WCGR3] > + wldrw wCSSF, r0, MMX_WCSSF > + wldrw wCASF, r0, MMX_WCASF > + wldrw wCGR0, r0, MMX_WCGR0 > + wldrw wCGR1, r0, MMX_WCGR1 > + wldrw wCGR2, r0, MMX_WCGR2 > + wldrw wCGR3, r0, MMX_WCGR3 > > @ clear CUP/MUP (only if r1 != 0) > teq r1, #0 > diff --git a/arch/arm/kernel/iwmmxt.h b/arch/arm/kernel/iwmmxt.h > new file mode 100644 > index 000000000000..fb627286f5bb > --- /dev/null > +++ b/arch/arm/kernel/iwmmxt.h > @@ -0,0 +1,47 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#ifndef __IWMMXT_H__ > +#define __IWMMXT_H__ > + > +.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > +.set .LwR\b, \b > +.set .Lr\b, \b > +.endr > + > +.set .LwCSSF, 0x2 > +.set .LwCASF, 0x3 > +.set .LwCGR0, 0x8 > +.set .LwCGR1, 0x9 > +.set .LwCGR2, 0xa > +.set .LwCGR3, 0xb > + > +.macro wldrd, reg:req, base:req, offset:req > +.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wldrw, reg:req, base:req, offset:req > +.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wstrd, reg:req, base:req, offset:req > +.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wstrw, reg:req, base:req, offset:req > +.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +#ifdef __clang__ > + > +#define wCon c1 > + > +.macro tmrc, dest:req, control:req > +mrc p1, 0, \dest, \control, c0, 0 > +.endm > + > +.macro tmcr, control:req, src:req > +mcr p1, 0, \src, \control, c0, 0 > +.endm > +#endif > + > +#endif > -- > 2.29.1.341.ge80a0c044ae-goog >
On Sat, Nov 7, 2020 at 12:29 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Sat, 7 Nov 2020 at 01:11, Jian Cai <jiancai@google.com> wrote: > > > > This patch replaces 6 IWMMXT instructions Clang's integrated assembler > > does not support in iwmmxt.S using macros, while making sure GNU > > assembler still emit the same instructions. This should be easier than > > providing full IWMMXT support in Clang. > > > > "Intel Wireless MMX Technology - Developer Guide - August, 2002" should > > be referenced for the encoding schemes of these extensions. > > > > Link: https://github.com/ClangBuiltLinux/linux/issues/975 > > > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com> > > Suggested-by: Ard Biesheuvel <ardb@kernel.org> > > Signed-off-by: Jian Cai <jiancai@google.com> > > Please make sure you test this carefully on BE32, as the instruction > byte order used by .inst is LE IIRC Unless that was a recent-ish change in GAS, it looks like I get the same disassembly/encodings before/after this patch for CONFIG_BIG_ENDIAN with GNU as. $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 defconfig $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 menuconfig <enable CPU_BIG_ENDIAN> $ grep BIG_ENDIAN .config CONFIG_CPU_BIG_ENDIAN=y CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 arch/arm/kernel/iwmmxt.o $ arm-linux-gnueabi-objdump -dr arch/arm/kernel/iwmmxt.o > gas_before.txt $ b4 am https://lore.kernel.org/lkml/20201107001056.225807-1-jiancai@google.com/ -o - | git am $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 arch/arm/kernel/iwmmxt.o $ arm-linux-gnueabi-objdump -dr arch/arm/kernel/iwmmxt.o > gas_after.txt $ diff -u gas_before.txt gas_after.txt $ echo $? 0 (Orthogonal, it looks like llvm-objdump has issues decoding elf32-bigarm that we'll need to fix.) Either way the patch LGTM for IWMMXT, thanks Jian for the patch and Ard for the suggestions. Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> Tested-by: Nick Desaulniers <ndesaulniers@google.com>
On Tue, 10 Nov 2020 at 02:55, Nick Desaulniers <ndesaulniers@google.com> wrote: > > On Sat, Nov 7, 2020 at 12:29 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > On Sat, 7 Nov 2020 at 01:11, Jian Cai <jiancai@google.com> wrote: > > > > > > This patch replaces 6 IWMMXT instructions Clang's integrated assembler > > > does not support in iwmmxt.S using macros, while making sure GNU > > > assembler still emit the same instructions. This should be easier than > > > providing full IWMMXT support in Clang. > > > > > > "Intel Wireless MMX Technology - Developer Guide - August, 2002" should > > > be referenced for the encoding schemes of these extensions. > > > > > > Link: https://github.com/ClangBuiltLinux/linux/issues/975 > > > > > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com> > > > Suggested-by: Ard Biesheuvel <ardb@kernel.org> > > > Signed-off-by: Jian Cai <jiancai@google.com> > > > > Please make sure you test this carefully on BE32, as the instruction > > byte order used by .inst is LE IIRC > > Unless that was a recent-ish change in GAS, it looks like I get the > same disassembly/encodings before/after this patch for > CONFIG_BIG_ENDIAN with GNU as. > > $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 defconfig > $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 menuconfig > <enable CPU_BIG_ENDIAN> > $ grep BIG_ENDIAN .config > CONFIG_CPU_BIG_ENDIAN=y > CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y > $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 > arch/arm/kernel/iwmmxt.o > $ arm-linux-gnueabi-objdump -dr arch/arm/kernel/iwmmxt.o > gas_before.txt > $ b4 am https://lore.kernel.org/lkml/20201107001056.225807-1-jiancai@google.com/ > -o - | git am > $ ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- make CC=clang -j71 > arch/arm/kernel/iwmmxt.o > $ arm-linux-gnueabi-objdump -dr arch/arm/kernel/iwmmxt.o > gas_after.txt > $ diff -u gas_before.txt gas_after.txt > $ echo $? > 0 > > (Orthogonal, it looks like llvm-objdump has issues decoding > elf32-bigarm that we'll need to fix.) > > Either way the patch LGTM for IWMMXT, thanks Jian for the patch and > Ard for the suggestions. > > Reviewed-by: Nick Desaulniers <ndesaulniers@google.com> > Tested-by: Nick Desaulniers <ndesaulniers@google.com> BE32 != BE8 Please use, e.g., ixp4xx_defconfig with IWMMXT and BE enabled. It seems like .inst does the right thing here, i.e., the assembler knows that it should emit BE for BE32 and LE for BE8, but it needs to be confirmed.
On Mon, Nov 9, 2020 at 11:36 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > BE32 != BE8 Oh? Sorry, what does BE8 stand for? arch/arm/mm/Kconfig says: CONFIG_CPU_ENDIAN_BE8 Support for the BE-8 (big-endian) mode on ARMv6 and ARMv7 processors. vs: CPU_ENDIAN_BE32 Support for the BE-32 (big-endian) mode on pre-ARMv6 processors. So BE8 seems newer? It looks like in my tests, enabling CPU_BIG_ENDIAN via menuconfig enabled CPU_ENDIAN_BE8. > > Please use, e.g., ixp4xx_defconfig with IWMMXT and BE enabled. It > seems like .inst does the right thing here, i.e., the assembler knows > that it should emit BE for BE32 and LE for BE8, but it needs to be > confirmed. Ah and ixp4xx_defconfig selects CPU_ENDIAN_BE32. Yep, and the disassemblies of those match, too.
On Tue, Nov 10, 2020 at 12:10 PM Jian Cai <jiancai@google.com> wrote: > > I tried to verify with ixp4xx_defconfig, and I noticed it also used CONFIG_CPU_BIG_ENDIAN=y to enable big endianness as follows, > > linux$ grep ENDIAN arch/arm/configs/ixp4xx_defconfig > CONFIG_CPU_BIG_ENDIAN=y > > Also it appeared arch/arm/kernel/iwmmxt.o was not built with ixp4xx_defconfig. The commands I used > > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make CC=clang ixp4xx_defconfig > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j32 CC=clang > linux$ ls arch/arm/kernel/iwmmxt.o > ls: cannot access 'arch/arm/kernel/iwmmxt.o': No such file or directory > > Did I miss any steps? Yes, you need to manually enable CONFIG_IWMMXT in menuconfig or via `scripts/configs -e`.
On Tue, Nov 10, 2020 at 9:11 PM 'Nick Desaulniers' via Clang Built Linux <clang-built-linux@googlegroups.com> wrote: > > On Tue, Nov 10, 2020 at 12:10 PM Jian Cai <jiancai@google.com> wrote: > > > > I tried to verify with ixp4xx_defconfig, and I noticed it also used CONFIG_CPU_BIG_ENDIAN=y to enable big endianness as follows, > > > > linux$ grep ENDIAN arch/arm/configs/ixp4xx_defconfig > > CONFIG_CPU_BIG_ENDIAN=y > > > > Also it appeared arch/arm/kernel/iwmmxt.o was not built with ixp4xx_defconfig. The commands I used > > > > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make CC=clang ixp4xx_defconfig > > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j32 CC=clang > > linux$ ls arch/arm/kernel/iwmmxt.o > > ls: cannot access 'arch/arm/kernel/iwmmxt.o': No such file or directory > > > > Did I miss any steps? > > Yes, you need to manually enable CONFIG_IWMMXT in menuconfig or via > `scripts/configs -e`. To clarify: ixp4xx and pxa3xx were two platforms based on the XScale core. ixp4xx was commonly used in big-endian mode but lacked iWMMXt. pxa3xx had iWMMXt but doesn't allow enabling big-endian mode because of a Kconfig dependency, meaning that nobody has ever tried it, and it's likely broken. Later 'mvebu' parts (Armada 510) do have iWMMXt and allow big-endian mode, but those are BE8, with non-reversed byteorder for the instructions. So none of this matters in practice, but it's very satifiying to know it is finally all working with the integrated assembler in all those combinations, at least in theory! Arnd
On Tue, 10 Nov 2020 at 21:38, Arnd Bergmann <arnd@kernel.org> wrote: > > On Tue, Nov 10, 2020 at 9:11 PM 'Nick Desaulniers' via Clang Built > Linux <clang-built-linux@googlegroups.com> wrote: > > > > On Tue, Nov 10, 2020 at 12:10 PM Jian Cai <jiancai@google.com> wrote: > > > > > > I tried to verify with ixp4xx_defconfig, and I noticed it also used CONFIG_CPU_BIG_ENDIAN=y to enable big endianness as follows, > > > > > > linux$ grep ENDIAN arch/arm/configs/ixp4xx_defconfig > > > CONFIG_CPU_BIG_ENDIAN=y > > > > > > Also it appeared arch/arm/kernel/iwmmxt.o was not built with ixp4xx_defconfig. The commands I used > > > > > > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make CC=clang ixp4xx_defconfig > > > linux$ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make -j32 CC=clang > > > linux$ ls arch/arm/kernel/iwmmxt.o > > > ls: cannot access 'arch/arm/kernel/iwmmxt.o': No such file or directory > > > > > > Did I miss any steps? > > > > Yes, you need to manually enable CONFIG_IWMMXT in menuconfig or via > > `scripts/configs -e`. > > To clarify: ixp4xx and pxa3xx were two platforms based on the XScale core. > ixp4xx was commonly used in big-endian mode but lacked iWMMXt. pxa3xx > had iWMMXt but doesn't allow enabling big-endian mode because of a Kconfig > dependency, meaning that nobody has ever tried it, and it's likely broken. > > Later 'mvebu' parts (Armada 510) do have iWMMXt and allow big-endian > mode, but those are BE8, with non-reversed byteorder for the instructions. > > So none of this matters in practice, but it's very satifiying to know > it is finally > all working with the integrated assembler in all those combinations, at > least in theory! > Thanks for the perspective. I wasn't aware of all these details, but I just wanted to confirm that .inst works as expected in all configurations.
On Sat, 7 Nov 2020 at 01:11, Jian Cai <jiancai@google.com> wrote: > > This patch replaces 6 IWMMXT instructions Clang's integrated assembler > does not support in iwmmxt.S using macros, while making sure GNU > assembler still emit the same instructions. This should be easier than > providing full IWMMXT support in Clang. > > "Intel Wireless MMX Technology - Developer Guide - August, 2002" should > be referenced for the encoding schemes of these extensions. > > Link: https://github.com/ClangBuiltLinux/linux/issues/975 > > Suggested-by: Nick Desaulniers <ndesaulniers@google.com> > Suggested-by: Ard Biesheuvel <ardb@kernel.org> > Signed-off-by: Jian Cai <jiancai@google.com> For the change itself, Acked-by: Ard Biesheuvel <ardb@kernel.org> Although I must admit I am still on the fence when it comes to the policy around rewriting perfectly valid code like this to accommodate a toolchain that nobody is likely to use to build the code in question. Perhaps we should at least add some rationale to the commit log why Clang's integrated assembler is something we should care about? I take it this is not about diagnostics or CFI but simply about avoiding the need to carry cross-binutils in the first place? > --- > arch/arm/kernel/iwmmxt.S | 89 ++++++++++++++++++++-------------------- > arch/arm/kernel/iwmmxt.h | 47 +++++++++++++++++++++ > 2 files changed, 92 insertions(+), 44 deletions(-) > create mode 100644 arch/arm/kernel/iwmmxt.h > > diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S > index 0dcae787b004..d2b4ac06e4ed 100644 > --- a/arch/arm/kernel/iwmmxt.S > +++ b/arch/arm/kernel/iwmmxt.S > @@ -16,6 +16,7 @@ > #include <asm/thread_info.h> > #include <asm/asm-offsets.h> > #include <asm/assembler.h> > +#include "iwmmxt.h" > > #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) > #define PJ4(code...) code > @@ -113,33 +114,33 @@ concan_save: > > concan_dump: > > - wstrw wCSSF, [r1, #MMX_WCSSF] > - wstrw wCASF, [r1, #MMX_WCASF] > - wstrw wCGR0, [r1, #MMX_WCGR0] > - wstrw wCGR1, [r1, #MMX_WCGR1] > - wstrw wCGR2, [r1, #MMX_WCGR2] > - wstrw wCGR3, [r1, #MMX_WCGR3] > + wstrw wCSSF, r1, MMX_WCSSF > + wstrw wCASF, r1, MMX_WCASF > + wstrw wCGR0, r1, MMX_WCGR0 > + wstrw wCGR1, r1, MMX_WCGR1 > + wstrw wCGR2, r1, MMX_WCGR2 > + wstrw wCGR3, r1, MMX_WCGR3 > > 1: @ MUP? wRn > tst r2, #0x2 > beq 2f > > - wstrd wR0, [r1, #MMX_WR0] > - wstrd wR1, [r1, #MMX_WR1] > - wstrd wR2, [r1, #MMX_WR2] > - wstrd wR3, [r1, #MMX_WR3] > - wstrd wR4, [r1, #MMX_WR4] > - wstrd wR5, [r1, #MMX_WR5] > - wstrd wR6, [r1, #MMX_WR6] > - wstrd wR7, [r1, #MMX_WR7] > - wstrd wR8, [r1, #MMX_WR8] > - wstrd wR9, [r1, #MMX_WR9] > - wstrd wR10, [r1, #MMX_WR10] > - wstrd wR11, [r1, #MMX_WR11] > - wstrd wR12, [r1, #MMX_WR12] > - wstrd wR13, [r1, #MMX_WR13] > - wstrd wR14, [r1, #MMX_WR14] > - wstrd wR15, [r1, #MMX_WR15] > + wstrd wR0, r1, MMX_WR0 > + wstrd wR1, r1, MMX_WR1 > + wstrd wR2, r1, MMX_WR2 > + wstrd wR3, r1, MMX_WR3 > + wstrd wR4, r1, MMX_WR4 > + wstrd wR5, r1, MMX_WR5 > + wstrd wR6, r1, MMX_WR6 > + wstrd wR7, r1, MMX_WR7 > + wstrd wR8, r1, MMX_WR8 > + wstrd wR9, r1, MMX_WR9 > + wstrd wR10, r1, MMX_WR10 > + wstrd wR11, r1, MMX_WR11 > + wstrd wR12, r1, MMX_WR12 > + wstrd wR13, r1, MMX_WR13 > + wstrd wR14, r1, MMX_WR14 > + wstrd wR15, r1, MMX_WR15 > > 2: teq r0, #0 @ anything to load? > reteq lr @ if not, return > @@ -147,30 +148,30 @@ concan_dump: > concan_load: > > @ Load wRn > - wldrd wR0, [r0, #MMX_WR0] > - wldrd wR1, [r0, #MMX_WR1] > - wldrd wR2, [r0, #MMX_WR2] > - wldrd wR3, [r0, #MMX_WR3] > - wldrd wR4, [r0, #MMX_WR4] > - wldrd wR5, [r0, #MMX_WR5] > - wldrd wR6, [r0, #MMX_WR6] > - wldrd wR7, [r0, #MMX_WR7] > - wldrd wR8, [r0, #MMX_WR8] > - wldrd wR9, [r0, #MMX_WR9] > - wldrd wR10, [r0, #MMX_WR10] > - wldrd wR11, [r0, #MMX_WR11] > - wldrd wR12, [r0, #MMX_WR12] > - wldrd wR13, [r0, #MMX_WR13] > - wldrd wR14, [r0, #MMX_WR14] > - wldrd wR15, [r0, #MMX_WR15] > + wldrd wR0, r0, MMX_WR0 > + wldrd wR1, r0, MMX_WR1 > + wldrd wR2, r0, MMX_WR2 > + wldrd wR3, r0, MMX_WR3 > + wldrd wR4, r0, MMX_WR4 > + wldrd wR5, r0, MMX_WR5 > + wldrd wR6, r0, MMX_WR6 > + wldrd wR7, r0, MMX_WR7 > + wldrd wR8, r0, MMX_WR8 > + wldrd wR9, r0, MMX_WR9 > + wldrd wR10, r0, MMX_WR10 > + wldrd wR11, r0, MMX_WR11 > + wldrd wR12, r0, MMX_WR12 > + wldrd wR13, r0, MMX_WR13 > + wldrd wR14, r0, MMX_WR14 > + wldrd wR15, r0, MMX_WR15 > > @ Load wCx > - wldrw wCSSF, [r0, #MMX_WCSSF] > - wldrw wCASF, [r0, #MMX_WCASF] > - wldrw wCGR0, [r0, #MMX_WCGR0] > - wldrw wCGR1, [r0, #MMX_WCGR1] > - wldrw wCGR2, [r0, #MMX_WCGR2] > - wldrw wCGR3, [r0, #MMX_WCGR3] > + wldrw wCSSF, r0, MMX_WCSSF > + wldrw wCASF, r0, MMX_WCASF > + wldrw wCGR0, r0, MMX_WCGR0 > + wldrw wCGR1, r0, MMX_WCGR1 > + wldrw wCGR2, r0, MMX_WCGR2 > + wldrw wCGR3, r0, MMX_WCGR3 > > @ clear CUP/MUP (only if r1 != 0) > teq r1, #0 > diff --git a/arch/arm/kernel/iwmmxt.h b/arch/arm/kernel/iwmmxt.h > new file mode 100644 > index 000000000000..fb627286f5bb > --- /dev/null > +++ b/arch/arm/kernel/iwmmxt.h > @@ -0,0 +1,47 @@ > +/* SPDX-License-Identifier: GPL-2.0 */ > + > +#ifndef __IWMMXT_H__ > +#define __IWMMXT_H__ > + > +.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 > +.set .LwR\b, \b > +.set .Lr\b, \b > +.endr > + > +.set .LwCSSF, 0x2 > +.set .LwCASF, 0x3 > +.set .LwCGR0, 0x8 > +.set .LwCGR1, 0x9 > +.set .LwCGR2, 0xa > +.set .LwCGR3, 0xb > + > +.macro wldrd, reg:req, base:req, offset:req > +.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wldrw, reg:req, base:req, offset:req > +.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wstrd, reg:req, base:req, offset:req > +.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +.macro wstrw, reg:req, base:req, offset:req > +.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) > +.endm > + > +#ifdef __clang__ > + > +#define wCon c1 > + > +.macro tmrc, dest:req, control:req > +mrc p1, 0, \dest, \control, c0, 0 > +.endm > + > +.macro tmcr, control:req, src:req > +mcr p1, 0, \src, \control, c0, 0 > +.endm > +#endif > + > +#endif > -- > 2.29.1.341.ge80a0c044ae-goog >
On Thu, Nov 12, 2020 at 9:42 AM Ard Biesheuvel <ardb@kernel.org> wrote: > Although I must admit I am still on the fence when it comes to the > policy around rewriting perfectly valid code like this to accommodate > a toolchain that nobody is likely to use to build the code in > question. > > Perhaps we should at least add some rationale to the commit log why > Clang's integrated assembler is something we should care about? This is one of the last bits of kernel code that could be compiled but not assembled with clang. Once all of it works with IAS, we no longer need to special-case 32-bit Arm in Kbuild, or turn off CONFIG_IWMMXT when build-testing. Arnd
diff --git a/arch/arm/kernel/iwmmxt.S b/arch/arm/kernel/iwmmxt.S index 0dcae787b004..d2b4ac06e4ed 100644 --- a/arch/arm/kernel/iwmmxt.S +++ b/arch/arm/kernel/iwmmxt.S @@ -16,6 +16,7 @@ #include <asm/thread_info.h> #include <asm/asm-offsets.h> #include <asm/assembler.h> +#include "iwmmxt.h" #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) #define PJ4(code...) code @@ -113,33 +114,33 @@ concan_save: concan_dump: - wstrw wCSSF, [r1, #MMX_WCSSF] - wstrw wCASF, [r1, #MMX_WCASF] - wstrw wCGR0, [r1, #MMX_WCGR0] - wstrw wCGR1, [r1, #MMX_WCGR1] - wstrw wCGR2, [r1, #MMX_WCGR2] - wstrw wCGR3, [r1, #MMX_WCGR3] + wstrw wCSSF, r1, MMX_WCSSF + wstrw wCASF, r1, MMX_WCASF + wstrw wCGR0, r1, MMX_WCGR0 + wstrw wCGR1, r1, MMX_WCGR1 + wstrw wCGR2, r1, MMX_WCGR2 + wstrw wCGR3, r1, MMX_WCGR3 1: @ MUP? wRn tst r2, #0x2 beq 2f - wstrd wR0, [r1, #MMX_WR0] - wstrd wR1, [r1, #MMX_WR1] - wstrd wR2, [r1, #MMX_WR2] - wstrd wR3, [r1, #MMX_WR3] - wstrd wR4, [r1, #MMX_WR4] - wstrd wR5, [r1, #MMX_WR5] - wstrd wR6, [r1, #MMX_WR6] - wstrd wR7, [r1, #MMX_WR7] - wstrd wR8, [r1, #MMX_WR8] - wstrd wR9, [r1, #MMX_WR9] - wstrd wR10, [r1, #MMX_WR10] - wstrd wR11, [r1, #MMX_WR11] - wstrd wR12, [r1, #MMX_WR12] - wstrd wR13, [r1, #MMX_WR13] - wstrd wR14, [r1, #MMX_WR14] - wstrd wR15, [r1, #MMX_WR15] + wstrd wR0, r1, MMX_WR0 + wstrd wR1, r1, MMX_WR1 + wstrd wR2, r1, MMX_WR2 + wstrd wR3, r1, MMX_WR3 + wstrd wR4, r1, MMX_WR4 + wstrd wR5, r1, MMX_WR5 + wstrd wR6, r1, MMX_WR6 + wstrd wR7, r1, MMX_WR7 + wstrd wR8, r1, MMX_WR8 + wstrd wR9, r1, MMX_WR9 + wstrd wR10, r1, MMX_WR10 + wstrd wR11, r1, MMX_WR11 + wstrd wR12, r1, MMX_WR12 + wstrd wR13, r1, MMX_WR13 + wstrd wR14, r1, MMX_WR14 + wstrd wR15, r1, MMX_WR15 2: teq r0, #0 @ anything to load? reteq lr @ if not, return @@ -147,30 +148,30 @@ concan_dump: concan_load: @ Load wRn - wldrd wR0, [r0, #MMX_WR0] - wldrd wR1, [r0, #MMX_WR1] - wldrd wR2, [r0, #MMX_WR2] - wldrd wR3, [r0, #MMX_WR3] - wldrd wR4, [r0, #MMX_WR4] - wldrd wR5, [r0, #MMX_WR5] - wldrd wR6, [r0, #MMX_WR6] - wldrd wR7, [r0, #MMX_WR7] - wldrd wR8, [r0, #MMX_WR8] - wldrd wR9, [r0, #MMX_WR9] - wldrd wR10, [r0, #MMX_WR10] - wldrd wR11, [r0, #MMX_WR11] - wldrd wR12, [r0, #MMX_WR12] - wldrd wR13, [r0, #MMX_WR13] - wldrd wR14, [r0, #MMX_WR14] - wldrd wR15, [r0, #MMX_WR15] + wldrd wR0, r0, MMX_WR0 + wldrd wR1, r0, MMX_WR1 + wldrd wR2, r0, MMX_WR2 + wldrd wR3, r0, MMX_WR3 + wldrd wR4, r0, MMX_WR4 + wldrd wR5, r0, MMX_WR5 + wldrd wR6, r0, MMX_WR6 + wldrd wR7, r0, MMX_WR7 + wldrd wR8, r0, MMX_WR8 + wldrd wR9, r0, MMX_WR9 + wldrd wR10, r0, MMX_WR10 + wldrd wR11, r0, MMX_WR11 + wldrd wR12, r0, MMX_WR12 + wldrd wR13, r0, MMX_WR13 + wldrd wR14, r0, MMX_WR14 + wldrd wR15, r0, MMX_WR15 @ Load wCx - wldrw wCSSF, [r0, #MMX_WCSSF] - wldrw wCASF, [r0, #MMX_WCASF] - wldrw wCGR0, [r0, #MMX_WCGR0] - wldrw wCGR1, [r0, #MMX_WCGR1] - wldrw wCGR2, [r0, #MMX_WCGR2] - wldrw wCGR3, [r0, #MMX_WCGR3] + wldrw wCSSF, r0, MMX_WCSSF + wldrw wCASF, r0, MMX_WCASF + wldrw wCGR0, r0, MMX_WCGR0 + wldrw wCGR1, r0, MMX_WCGR1 + wldrw wCGR2, r0, MMX_WCGR2 + wldrw wCGR3, r0, MMX_WCGR3 @ clear CUP/MUP (only if r1 != 0) teq r1, #0 diff --git a/arch/arm/kernel/iwmmxt.h b/arch/arm/kernel/iwmmxt.h new file mode 100644 index 000000000000..fb627286f5bb --- /dev/null +++ b/arch/arm/kernel/iwmmxt.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __IWMMXT_H__ +#define __IWMMXT_H__ + +.irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +.set .LwR\b, \b +.set .Lr\b, \b +.endr + +.set .LwCSSF, 0x2 +.set .LwCASF, 0x3 +.set .LwCGR0, 0x8 +.set .LwCGR1, 0x9 +.set .LwCGR2, 0xa +.set .LwCGR3, 0xb + +.macro wldrd, reg:req, base:req, offset:req +.inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wldrw, reg:req, base:req, offset:req +.inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrd, reg:req, base:req, offset:req +.inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +.macro wstrw, reg:req, base:req, offset:req +.inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) +.endm + +#ifdef __clang__ + +#define wCon c1 + +.macro tmrc, dest:req, control:req +mrc p1, 0, \dest, \control, c0, 0 +.endm + +.macro tmcr, control:req, src:req +mcr p1, 0, \src, \control, c0, 0 +.endm +#endif + +#endif
This patch replaces 6 IWMMXT instructions Clang's integrated assembler does not support in iwmmxt.S using macros, while making sure GNU assembler still emit the same instructions. This should be easier than providing full IWMMXT support in Clang. "Intel Wireless MMX Technology - Developer Guide - August, 2002" should be referenced for the encoding schemes of these extensions. Link: https://github.com/ClangBuiltLinux/linux/issues/975 Suggested-by: Nick Desaulniers <ndesaulniers@google.com> Suggested-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Jian Cai <jiancai@google.com> --- arch/arm/kernel/iwmmxt.S | 89 ++++++++++++++++++++-------------------- arch/arm/kernel/iwmmxt.h | 47 +++++++++++++++++++++ 2 files changed, 92 insertions(+), 44 deletions(-) create mode 100644 arch/arm/kernel/iwmmxt.h