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

MIPS: Use WSBH/DSBH/DSHD on Loongson 3A

Signed-off-by: chenj <chenj@lemote.com>
Cc: linux-mips@linux-mips.org
Cc: chenhc@lemote.com
Patchwork: https://patchwork.linux-mips.org/patch/7542/
Patchwork: https://patchwork.linux-mips.org/patch/7550/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Chen Jie and committed by
Ralf Baechle
3c09bae4 0f33be00

+36 -7
+10
arch/mips/include/asm/cpu-features.h
··· 231 231 #define cpu_has_clo_clz cpu_has_mips_r 232 232 #endif 233 233 234 + /* 235 + * MIPS32 R2, MIPS64 R2, Loongson 3A and Octeon have WSBH. 236 + * MIPS64 R2, Loongson 3A and Octeon have WSBH, DSBH and DSHD. 237 + * This indicates the availability of WSBH and in case of 64 bit CPUs also 238 + * DSBH and DSHD. 239 + */ 240 + #ifndef cpu_has_wsbh 241 + #define cpu_has_wsbh cpu_has_mips_r2 242 + #endif 243 + 234 244 #ifndef cpu_has_dsp 235 245 #define cpu_has_dsp (cpu_data[0].ases & MIPS_ASE_DSP) 236 246 #endif
+1
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
··· 57 57 #define cpu_has_vint 0 58 58 #define cpu_has_veic 0 59 59 #define cpu_hwrena_impl_bits 0xc0000000 60 + #define cpu_has_wsbh 1 60 61 61 62 #define cpu_has_rixi (cpu_data[0].cputype != CPU_CAVIUM_OCTEON) 62 63
+2
arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
··· 59 59 #define cpu_has_watch 1 60 60 #define cpu_has_local_ebase 0 61 61 62 + #define cpu_has_wsbh IS_ENABLED(CONFIG_CPU_LOONGSON3) 63 + 62 64 #endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
+14 -4
arch/mips/include/uapi/asm/swab.h
··· 13 13 14 14 #define __SWAB_64_THRU_32__ 15 15 16 - #if defined(__mips_isa_rev) && (__mips_isa_rev >= 2) 16 + #if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) || \ 17 + defined(_MIPS_ARCH_LOONGSON3A) 17 18 18 19 static inline __attribute_const__ __u16 __arch_swab16(__u16 x) 19 20 { 20 21 __asm__( 22 + " .set push \n" 23 + " .set arch=mips32r2 \n" 21 24 " wsbh %0, %1 \n" 25 + " .set pop \n" 22 26 : "=r" (x) 23 27 : "r" (x)); 24 28 ··· 33 29 static inline __attribute_const__ __u32 __arch_swab32(__u32 x) 34 30 { 35 31 __asm__( 32 + " .set push \n" 33 + " .set arch=mips32r2 \n" 36 34 " wsbh %0, %1 \n" 37 35 " rotr %0, %0, 16 \n" 36 + " .set pop \n" 38 37 : "=r" (x) 39 38 : "r" (x)); 40 39 ··· 53 46 static inline __attribute_const__ __u64 __arch_swab64(__u64 x) 54 47 { 55 48 __asm__( 56 - " dsbh %0, %1\n" 57 - " dshd %0, %0" 49 + " .set push \n" 50 + " .set arch=mips64r2 \n" 51 + " dsbh %0, %1 \n" 52 + " dshd %0, %0 \n" 53 + " .set pop \n" 58 54 : "=r" (x) 59 55 : "r" (x)); 60 56 ··· 65 55 } 66 56 #define __arch_swab64 __arch_swab64 67 57 #endif /* __mips64 */ 68 - #endif /* MIPS R2 or newer */ 58 + #endif /* MIPS R2 or newer or Loongson 3A */ 69 59 #endif /* _ASM_SWAB_H */
+8 -2
arch/mips/lib/csum_partial.S
··· 277 277 #endif 278 278 279 279 /* odd buffer alignment? */ 280 - #ifdef CONFIG_CPU_MIPSR2 280 + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3) 281 + .set push 282 + .set arch=mips32r2 281 283 wsbh v1, sum 282 284 movn sum, v1, t7 285 + .set pop 283 286 #else 284 287 beqz t7, 1f /* odd buffer alignment? */ 285 288 lui v1, 0x00ff ··· 729 726 addu sum, v1 730 727 #endif 731 728 732 - #ifdef CONFIG_CPU_MIPSR2 729 + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3) 730 + .set push 731 + .set arch=mips32r2 733 732 wsbh v1, sum 734 733 movn sum, v1, odd 734 + .set pop 735 735 #else 736 736 beqz odd, 1f /* odd buffer alignment? */ 737 737 lui v1, 0x00ff
+1 -1
arch/mips/net/bpf_jit.c
··· 1263 1263 emit_half_load(r_A, r_skb, off, ctx); 1264 1264 #ifdef CONFIG_CPU_LITTLE_ENDIAN 1265 1265 /* This needs little endian fixup */ 1266 - if (cpu_has_mips_r2) { 1266 + if (cpu_has_wsbh) { 1267 1267 /* R2 and later have the wsbh instruction */ 1268 1268 emit_wsbh(r_A, r_A, ctx); 1269 1269 } else {