]> granicus.if.org Git - libvpx/commitdiff
Refine MMI & MSA detection for mips
authorjinbo <jinbo-hf@loongson.cn>
Sat, 15 Aug 2020 09:20:36 +0000 (17:20 +0800)
committerjinbo <jinbo-hf@loongson.cn>
Tue, 18 Aug 2020 23:57:21 +0000 (07:57 +0800)
1.Add compile check to probe the native ability of
toolchain to decide whether a feature can be enabled.
2.Add runtime check to probe cpu supported features.
MSA will be prefered if MSA and MMI are both supported.
3.You can configure and build as following commands:
./configure --cpu=loongson3a && make -j4

Change-Id: I057553216dbc79cfaba9c691d5f4cdab144e1123

build/make/Makefile
build/make/configure.sh
build/make/rtcd.pl
vp8/common/generic/systemdependent.c
vpx_ports/mips.h [new file with mode: 0644]
vpx_ports/mips_cpudetect.c [new file with mode: 0644]
vpx_ports/vpx_ports.mk

index be28102295777f0a12356ab0028ccd45635bf877..9ca97c8c6406279556943df2ce297d12a7eb05f2 100644 (file)
@@ -147,6 +147,10 @@ $(BUILD_PFX)%_avx512.c.o: CFLAGS += -mavx512f -mavx512cd -mavx512bw -mavx512dq -
 $(BUILD_PFX)%_vsx.c.d: CFLAGS += -maltivec -mvsx
 $(BUILD_PFX)%_vsx.c.o: CFLAGS += -maltivec -mvsx
 
+# MIPS
+$(BUILD_PFX)%_msa.c.d: CFLAGS += -mmsa
+$(BUILD_PFX)%_msa.c.o: CFLAGS += -mmsa
+
 $(BUILD_PFX)%.c.d: %.c
        $(if $(quiet),@echo "    [DEP] $@")
        $(qexec)mkdir -p $(dir $@)
index 206b54f775c1c501180d3249ef99d99018e982c5..f8aa102775975ea82d0b698f4a196945c63ab95c 100644 (file)
@@ -1195,25 +1195,27 @@ EOF
             check_add_asflags -mips64r6 -mabi=64 -mhard-float -mfp64
             check_add_ldflags -mips64r6 -mabi=64 -mfp64
             ;;
+          loongson3*)
+            check_cflags -march=loongson3a && soft_enable mmi \
+              || disable_feature mmi
+            check_cflags -mmsa && soft_enable msa \
+              || disable_feature msa
+            tgt_isa=loongson3a
+            ;;
         esac
 
+        if enabled mmi || enabled msa; then
+          soft_enable runtime_cpu_detect
+        fi
+
         if enabled msa; then
           # TODO(libyuv:793)
           # The new mips functions in libyuv do not build
           # with the toolchains we currently use for testing.
           soft_disable libyuv
-
-          add_cflags -mmsa
-          add_asflags -mmsa
-          add_ldflags -mmsa
         fi
       fi
 
-      if enabled mmi; then
-        tgt_isa=loongson3a
-        check_add_ldflags -march=loongson3a
-      fi
-
       check_add_cflags -march=${tgt_isa}
       check_add_asflags -march=${tgt_isa}
       check_add_asflags -KPIC
index 7483200411a7aafde1ba620ea0d448b4f30d6a09..acb9f6e466735343af66d2271b1dbdb107404423 100755 (executable)
@@ -315,14 +315,26 @@ EOF
 
 sub mips() {
   determine_indirection("c", @ALL_ARCHS);
+
+  # Assign the helper variable for each enabled extension
+  foreach my $opt (@ALL_ARCHS) {
+    my $opt_uc = uc $opt;
+    eval "\$have_${opt}=\"flags & HAS_${opt_uc}\"";
+  }
+
   common_top;
 
   print <<EOF;
 #include "vpx_config.h"
 
 #ifdef RTCD_C
+#include "vpx_ports/mips.h"
 static void setup_rtcd_internal(void)
 {
+    int flags = mips_cpu_caps();
+
+    (void)flags;
+
 EOF
 
   set_function_pointers("c", @ALL_ARCHS);
@@ -410,24 +422,35 @@ if ($opts{arch} eq 'x86') {
   &require(@REQUIRES);
   x86;
 } elsif ($opts{arch} eq 'mips32' || $opts{arch} eq 'mips64') {
+  my $have_dspr2 = 0;
+  my $have_msa = 0;
+  my $have_mmi = 0;
   @ALL_ARCHS = filter("$opts{arch}");
   open CONFIG_FILE, $opts{config} or
     die "Error opening config file '$opts{config}': $!\n";
   while (<CONFIG_FILE>) {
     if (/HAVE_DSPR2=yes/) {
-      @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/);
-      last;
+      $have_dspr2 = 1;
     }
     if (/HAVE_MSA=yes/) {
-      @ALL_ARCHS = filter("$opts{arch}", qw/msa/);
-      last;
+      $have_msa = 1;
     }
     if (/HAVE_MMI=yes/) {
-      @ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
-      last;
+      $have_mmi = 1;
     }
   }
   close CONFIG_FILE;
+  if ($have_dspr2 == 1) {
+    @ALL_ARCHS = filter("$opts{arch}", qw/dspr2/);
+  } elsif ($have_msa == 1 && $have_mmi == 1) {
+    @ALL_ARCHS = filter("$opts{arch}", qw/mmi msa/);
+  } elsif ($have_msa == 1) {
+    @ALL_ARCHS = filter("$opts{arch}", qw/msa/);
+  } elsif ($have_mmi == 1) {
+    @ALL_ARCHS = filter("$opts{arch}", qw/mmi/);
+  } else {
+    unoptimized;
+  }
   mips;
 } elsif ($opts{arch} =~ /armv7\w?/) {
   @ALL_ARCHS = filter(qw/neon_asm neon/);
index 75ce7ef35964f1ea25853b9b8c9f2d9ca7e7ded1..cd1b02c9cc5b74381a3c0a30d935e5f145e7b2d2 100644 (file)
@@ -16,6 +16,8 @@
 #include "vpx_ports/x86.h"
 #elif VPX_ARCH_PPC
 #include "vpx_ports/ppc.h"
+#elif VPX_ARCH_MIPS
+#include "vpx_ports/mips.h"
 #endif
 #include "vp8/common/onyxc_int.h"
 #include "vp8/common/systemdependent.h"
@@ -96,6 +98,8 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) {
   ctx->cpu_caps = x86_simd_caps();
 #elif VPX_ARCH_PPC
   ctx->cpu_caps = ppc_simd_caps();
+#elif VPX_ARCH_MIPS
+  ctx->cpu_caps = mips_cpu_caps();
 #else
   // generic-gnu targets.
   ctx->cpu_caps = 0;
diff --git a/vpx_ports/mips.h b/vpx_ports/mips.h
new file mode 100644 (file)
index 0000000..bdc7525
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef VPX_PORTS_MIPS_H_
+#define VPX_PORTS_MIPS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAS_MMI 0x01
+#define HAS_MSA 0x02
+
+int mips_cpu_caps(void);
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif  // VPX_PORTS_MIPS_H_
diff --git a/vpx_ports/mips_cpudetect.c b/vpx_ports/mips_cpudetect.c
new file mode 100644 (file)
index 0000000..e0eca2d
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "./vpx_config.h"
+#include "vpx_ports/mips.h"
+
+#if CONFIG_RUNTIME_CPU_DETECT
+#if defined(__mips__) && defined(__linux__)
+int mips_cpu_caps(void) {
+  char cpuinfo_line[512];
+  int flag = 0x0;
+  FILE *f = fopen("/proc/cpuinfo", "r");
+  if (!f) {
+    // Assume nothing if /proc/cpuinfo is unavailable.
+    // This will occur for Chrome sandbox for Pepper or Render process.
+    return 0;
+  }
+  while (fgets(cpuinfo_line, sizeof(cpuinfo_line) - 1, f)) {
+    if (memcmp(cpuinfo_line, "cpu model", 9) == 0) {
+      // Workaround early kernel without mmi in ASEs line.
+      if (strstr(cpuinfo_line, "Loongson-3")) {
+        flag |= HAS_MMI;
+      } else if (strstr(cpuinfo_line, "Loongson-2K")) {
+        flag |= HAS_MMI | HAS_MSA;
+      }
+    }
+    if (memcmp(cpuinfo_line, "ASEs implemented", 16) == 0) {
+      if (strstr(cpuinfo_line, "loongson-mmi") &&
+          strstr(cpuinfo_line, "loongson-ext")) {
+        flag |= HAS_MMI;
+      }
+      if (strstr(cpuinfo_line, "msa")) {
+        flag |= HAS_MSA;
+      }
+      // ASEs is the last line, so we can break here.
+      break;
+    }
+  }
+  fclose(f);
+  return flag;
+}
+#else /* end __mips__ && __linux__ */
+#error \
+    "--enable-runtime-cpu-detect selected, but no CPU detection method " \
+"available for your platform. Reconfigure with --disable-runtime-cpu-detect."
+#endif
+#else /* end CONFIG_RUNTIME_CPU_DETECT */
+int mips_cpu_caps(void) { return 0; }
+#endif
index 2331773693f4c167a2f8a3b089520301915a7b9a..e5001be49674dfc64af06f2dead0ed223f2726ae 100644 (file)
@@ -42,6 +42,9 @@ PORTS_SRCS-$(VPX_ARCH_ARM) += arm.h
 PORTS_SRCS-$(VPX_ARCH_PPC) += ppc_cpudetect.c
 PORTS_SRCS-$(VPX_ARCH_PPC) += ppc.h
 
+PORTS_SRCS-$(VPX_ARCH_MIPS) += mips_cpudetect.c
+PORTS_SRCS-$(VPX_ARCH_MIPS) += mips.h
+
 ifeq ($(VPX_ARCH_MIPS), yes)
 PORTS_SRCS-yes += asmdefs_mmi.h
 endif