MIPS: strnlen_user.S: Fix a CPU_DADDI_WORKAROUNDS regression

Correct a regression introduced with 8453eebd [MIPS: Fix strnlen_user()
return value in case of overlong strings.] causing assembler warnings
and broken code generated in __strnlen_kernel_nocheck_asm:

arch/mips/lib/strnlen_user.S: Assembler messages:
arch/mips/lib/strnlen_user.S:64: Warning: Macro instruction expanded into multiple instructions in a branch delay slot

with the CPU_DADDI_WORKAROUNDS option set, resulting in the function
looping indefinitely upon mounting NFS root.

Use conditional assembly to avoid a microMIPS code size regression.
Using $at unconditionally would cause such a regression as there are no
16-bit instruction encodings available for ALU operations using this
register. Using $v1 unconditionally would produce short microMIPS
encodings, but would prevent this register from being used across calls
to this function.

The extra LI operation introduced is free, replacing a NOP originally
scheduled into the delay slot of the branch that follows.

Signed-off-by: Maciej W. Rozycki <macro@linux-mips.org>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/10205/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by Maciej W. Rozycki and committed by Ralf Baechle c4fca4fd 57b41758

Changed files
+13 -2
arch
mips
+13 -2
arch/mips/lib/strnlen_user.S
··· 34 34 FEXPORT(__strnlen_\func\()_nocheck_asm) 35 35 move v0, a0 36 36 PTR_ADDU a1, a0 # stop pointer 37 - 1: beq v0, a1, 1f # limit reached? 37 + 1: 38 + #ifdef CONFIG_CPU_DADDI_WORKAROUNDS 39 + .set noat 40 + li AT, 1 41 + #endif 42 + beq v0, a1, 1f # limit reached? 38 43 .ifeqs "\func", "kernel" 39 44 EX(lb, t0, (v0), .Lfault\@) 40 45 .else ··· 47 42 .endif 48 43 .set noreorder 49 44 bnez t0, 1b 50 - 1: PTR_ADDIU v0, 1 45 + 1: 46 + #ifndef CONFIG_CPU_DADDI_WORKAROUNDS 47 + PTR_ADDIU v0, 1 48 + #else 49 + PTR_ADDU v0, AT 50 + .set at 51 + #endif 51 52 .set reorder 52 53 PTR_SUBU v0, a0 53 54 jr ra