MIPS: Use WSBH/DSBH/DSHD on Loongson 3A
authorChen Jie <chenj@lemote.com>
Fri, 15 Aug 2014 08:56:58 +0000 (16:56 +0800)
committerRalf Baechle <ralf@linux-mips.org>
Mon, 22 Sep 2014 11:35:46 +0000 (13:35 +0200)
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>
arch/mips/include/asm/cpu-features.h
arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
arch/mips/include/asm/mach-loongson/cpu-feature-overrides.h
arch/mips/include/uapi/asm/swab.h
arch/mips/lib/csum_partial.S
arch/mips/net/bpf_jit.c

index e079598ae0516b9db2ae674ae15e89e00527d422..3325f3eb248c4cebabe44b9579d733f6a65046ae 100644 (file)
 #define cpu_has_clo_clz        cpu_has_mips_r
 #endif
 
+/*
+ * MIPS32 R2, MIPS64 R2, Loongson 3A and Octeon have WSBH.
+ * MIPS64 R2, Loongson 3A and Octeon have WSBH, DSBH and DSHD.
+ * This indicates the availability of WSBH and in case of 64 bit CPUs also
+ * DSBH and DSHD.
+ */
+#ifndef cpu_has_wsbh
+#define cpu_has_wsbh           cpu_has_mips_r2
+#endif
+
 #ifndef cpu_has_dsp
 #define cpu_has_dsp            (cpu_data[0].ases & MIPS_ASE_DSP)
 #endif
index cf80228728926d83b74e1c58366e740d6790d585..fa1f3cfbae8d70aa9dc0db696282bb1f8ed8f76f 100644 (file)
@@ -57,6 +57,7 @@
 #define cpu_has_vint           0
 #define cpu_has_veic           0
 #define cpu_hwrena_impl_bits   0xc0000000
+#define cpu_has_wsbh            1
 
 #define cpu_has_rixi           (cpu_data[0].cputype != CPU_CAVIUM_OCTEON)
 
index c0f3ef45c2c14f0e658feee183eabc6f8141ea9f..7d28f95b0512ea27e1aeb7fac6f22ecc561a45fd 100644 (file)
@@ -59,4 +59,6 @@
 #define cpu_has_watch          1
 #define cpu_has_local_ebase    0
 
+#define cpu_has_wsbh           IS_ENABLED(CONFIG_CPU_LOONGSON3)
+
 #endif /* __ASM_MACH_LOONGSON_CPU_FEATURE_OVERRIDES_H */
index ac9a8f9cd1fbfb53299e579661ce63d406cfee18..8f2d184dbe9f7adb43a32325e0061243c8f5fbf9 100644 (file)
 
 #define __SWAB_64_THRU_32__
 
-#if defined(__mips_isa_rev) && (__mips_isa_rev >= 2)
+#if (defined(__mips_isa_rev) && (__mips_isa_rev >= 2)) ||              \
+    defined(_MIPS_ARCH_LOONGSON3A)
 
 static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
 {
        __asm__(
+       "       .set    push                    \n"
+       "       .set    arch=mips32r2           \n"
        "       wsbh    %0, %1                  \n"
+       "       .set    pop                     \n"
        : "=r" (x)
        : "r" (x));
 
@@ -29,8 +33,11 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
 static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 {
        __asm__(
+       "       .set    push                    \n"
+       "       .set    arch=mips32r2           \n"
        "       wsbh    %0, %1                  \n"
        "       rotr    %0, %0, 16              \n"
+       "       .set    pop                     \n"
        : "=r" (x)
        : "r" (x));
 
@@ -46,8 +53,11 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
 static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
 {
        __asm__(
-       "       dsbh    %0, %1\n"
-       "       dshd    %0, %0"
+       "       .set    push                    \n"
+       "       .set    arch=mips64r2           \n"
+       "       dsbh    %0, %1                  \n"
+       "       dshd    %0, %0                  \n"
+       "       .set    pop                     \n"
        : "=r" (x)
        : "r" (x));
 
@@ -55,5 +65,5 @@ static inline __attribute_const__ __u64 __arch_swab64(__u64 x)
 }
 #define __arch_swab64 __arch_swab64
 #endif /* __mips64 */
-#endif /* MIPS R2 or newer  */
+#endif /* MIPS R2 or newer or Loongson 3A */
 #endif /* _ASM_SWAB_H */
index 9901237563c58922d213b9af10b9ed3c504b18e5..4c721e247ac9a001f4cc4c2335da851143ae1e8a 100644 (file)
@@ -277,9 +277,12 @@ LEAF(csum_partial)
 #endif
 
        /* odd buffer alignment? */
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3)
+       .set    push
+       .set    arch=mips32r2
        wsbh    v1, sum
        movn    sum, v1, t7
+       .set    pop
 #else
        beqz    t7, 1f                  /* odd buffer alignment? */
         lui    v1, 0x00ff
@@ -726,9 +729,12 @@ LEAF(csum_partial)
        addu    sum, v1
 #endif
 
-#ifdef CONFIG_CPU_MIPSR2
+#if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_LOONGSON3)
+       .set    push
+       .set    arch=mips32r2
        wsbh    v1, sum
        movn    sum, v1, odd
+       .set    pop
 #else
        beqz    odd, 1f                 /* odd buffer alignment? */
         lui    v1, 0x00ff
index 9f7ecbda250c2569daae114e9fae539407d00766..ae8cc847738939708a2e93b1c7f8608fd85034e5 100644 (file)
@@ -1263,7 +1263,7 @@ jmp_cmp:
                        emit_half_load(r_A, r_skb, off, ctx);
 #ifdef CONFIG_CPU_LITTLE_ENDIAN
                        /* This needs little endian fixup */
-                       if (cpu_has_mips_r2) {
+                       if (cpu_has_wsbh) {
                                /* R2 and later have the wsbh instruction */
                                emit_wsbh(r_A, r_A, ctx);
                        } else {