Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ARM: 9029/1: Make iwmmxt.S support Clang's integrated assembler

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. 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.

"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>
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Tested-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Jian Cai <jiancai@google.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>

authored by

Jian Cai and committed by
Russell King
3c9f5708 4d576cab

+92 -44
+45 -44
arch/arm/kernel/iwmmxt.S
··· 16 16 #include <asm/thread_info.h> 17 17 #include <asm/asm-offsets.h> 18 18 #include <asm/assembler.h> 19 + #include "iwmmxt.h" 19 20 20 21 #if defined(CONFIG_CPU_PJ4) || defined(CONFIG_CPU_PJ4B) 21 22 #define PJ4(code...) code ··· 114 113 115 114 concan_dump: 116 115 117 - wstrw wCSSF, [r1, #MMX_WCSSF] 118 - wstrw wCASF, [r1, #MMX_WCASF] 119 - wstrw wCGR0, [r1, #MMX_WCGR0] 120 - wstrw wCGR1, [r1, #MMX_WCGR1] 121 - wstrw wCGR2, [r1, #MMX_WCGR2] 122 - wstrw wCGR3, [r1, #MMX_WCGR3] 116 + wstrw wCSSF, r1, MMX_WCSSF 117 + wstrw wCASF, r1, MMX_WCASF 118 + wstrw wCGR0, r1, MMX_WCGR0 119 + wstrw wCGR1, r1, MMX_WCGR1 120 + wstrw wCGR2, r1, MMX_WCGR2 121 + wstrw wCGR3, r1, MMX_WCGR3 123 122 124 123 1: @ MUP? wRn 125 124 tst r2, #0x2 126 125 beq 2f 127 126 128 - wstrd wR0, [r1, #MMX_WR0] 129 - wstrd wR1, [r1, #MMX_WR1] 130 - wstrd wR2, [r1, #MMX_WR2] 131 - wstrd wR3, [r1, #MMX_WR3] 132 - wstrd wR4, [r1, #MMX_WR4] 133 - wstrd wR5, [r1, #MMX_WR5] 134 - wstrd wR6, [r1, #MMX_WR6] 135 - wstrd wR7, [r1, #MMX_WR7] 136 - wstrd wR8, [r1, #MMX_WR8] 137 - wstrd wR9, [r1, #MMX_WR9] 138 - wstrd wR10, [r1, #MMX_WR10] 139 - wstrd wR11, [r1, #MMX_WR11] 140 - wstrd wR12, [r1, #MMX_WR12] 141 - wstrd wR13, [r1, #MMX_WR13] 142 - wstrd wR14, [r1, #MMX_WR14] 143 - wstrd wR15, [r1, #MMX_WR15] 127 + wstrd wR0, r1, MMX_WR0 128 + wstrd wR1, r1, MMX_WR1 129 + wstrd wR2, r1, MMX_WR2 130 + wstrd wR3, r1, MMX_WR3 131 + wstrd wR4, r1, MMX_WR4 132 + wstrd wR5, r1, MMX_WR5 133 + wstrd wR6, r1, MMX_WR6 134 + wstrd wR7, r1, MMX_WR7 135 + wstrd wR8, r1, MMX_WR8 136 + wstrd wR9, r1, MMX_WR9 137 + wstrd wR10, r1, MMX_WR10 138 + wstrd wR11, r1, MMX_WR11 139 + wstrd wR12, r1, MMX_WR12 140 + wstrd wR13, r1, MMX_WR13 141 + wstrd wR14, r1, MMX_WR14 142 + wstrd wR15, r1, MMX_WR15 144 143 145 144 2: teq r0, #0 @ anything to load? 146 145 reteq lr @ if not, return ··· 148 147 concan_load: 149 148 150 149 @ Load wRn 151 - wldrd wR0, [r0, #MMX_WR0] 152 - wldrd wR1, [r0, #MMX_WR1] 153 - wldrd wR2, [r0, #MMX_WR2] 154 - wldrd wR3, [r0, #MMX_WR3] 155 - wldrd wR4, [r0, #MMX_WR4] 156 - wldrd wR5, [r0, #MMX_WR5] 157 - wldrd wR6, [r0, #MMX_WR6] 158 - wldrd wR7, [r0, #MMX_WR7] 159 - wldrd wR8, [r0, #MMX_WR8] 160 - wldrd wR9, [r0, #MMX_WR9] 161 - wldrd wR10, [r0, #MMX_WR10] 162 - wldrd wR11, [r0, #MMX_WR11] 163 - wldrd wR12, [r0, #MMX_WR12] 164 - wldrd wR13, [r0, #MMX_WR13] 165 - wldrd wR14, [r0, #MMX_WR14] 166 - wldrd wR15, [r0, #MMX_WR15] 150 + wldrd wR0, r0, MMX_WR0 151 + wldrd wR1, r0, MMX_WR1 152 + wldrd wR2, r0, MMX_WR2 153 + wldrd wR3, r0, MMX_WR3 154 + wldrd wR4, r0, MMX_WR4 155 + wldrd wR5, r0, MMX_WR5 156 + wldrd wR6, r0, MMX_WR6 157 + wldrd wR7, r0, MMX_WR7 158 + wldrd wR8, r0, MMX_WR8 159 + wldrd wR9, r0, MMX_WR9 160 + wldrd wR10, r0, MMX_WR10 161 + wldrd wR11, r0, MMX_WR11 162 + wldrd wR12, r0, MMX_WR12 163 + wldrd wR13, r0, MMX_WR13 164 + wldrd wR14, r0, MMX_WR14 165 + wldrd wR15, r0, MMX_WR15 167 166 168 167 @ Load wCx 169 - wldrw wCSSF, [r0, #MMX_WCSSF] 170 - wldrw wCASF, [r0, #MMX_WCASF] 171 - wldrw wCGR0, [r0, #MMX_WCGR0] 172 - wldrw wCGR1, [r0, #MMX_WCGR1] 173 - wldrw wCGR2, [r0, #MMX_WCGR2] 174 - wldrw wCGR3, [r0, #MMX_WCGR3] 168 + wldrw wCSSF, r0, MMX_WCSSF 169 + wldrw wCASF, r0, MMX_WCASF 170 + wldrw wCGR0, r0, MMX_WCGR0 171 + wldrw wCGR1, r0, MMX_WCGR1 172 + wldrw wCGR2, r0, MMX_WCGR2 173 + wldrw wCGR3, r0, MMX_WCGR3 175 174 176 175 @ clear CUP/MUP (only if r1 != 0) 177 176 teq r1, #0
+47
arch/arm/kernel/iwmmxt.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + 3 + #ifndef __IWMMXT_H__ 4 + #define __IWMMXT_H__ 5 + 6 + .irp b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 7 + .set .LwR\b, \b 8 + .set .Lr\b, \b 9 + .endr 10 + 11 + .set .LwCSSF, 0x2 12 + .set .LwCASF, 0x3 13 + .set .LwCGR0, 0x8 14 + .set .LwCGR1, 0x9 15 + .set .LwCGR2, 0xa 16 + .set .LwCGR3, 0xb 17 + 18 + .macro wldrd, reg:req, base:req, offset:req 19 + .inst 0xedd00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) 20 + .endm 21 + 22 + .macro wldrw, reg:req, base:req, offset:req 23 + .inst 0xfd900100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) 24 + .endm 25 + 26 + .macro wstrd, reg:req, base:req, offset:req 27 + .inst 0xedc00100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) 28 + .endm 29 + 30 + .macro wstrw, reg:req, base:req, offset:req 31 + .inst 0xfd800100 | (.L\reg << 12) | (.L\base << 16) | (\offset >> 2) 32 + .endm 33 + 34 + #ifdef __clang__ 35 + 36 + #define wCon c1 37 + 38 + .macro tmrc, dest:req, control:req 39 + mrc p1, 0, \dest, \control, c0, 0 40 + .endm 41 + 42 + .macro tmcr, control:req, src:req 43 + mcr p1, 0, \src, \control, c0, 0 44 + .endm 45 + #endif 46 + 47 + #endif