shithub: libvpx

Download patch

ref: ea6562f2fcd8ea6baa946eaad69cbb5aec5dd278
parent: 529c29bb0f6511a9b3e25177cece0d843827458b
author: jinbo <jinbo-hf@loongson.cn>
date: Sat Aug 15 13:20:36 EDT 2020

Refine MMI & MSA detection for mips

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

--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -147,6 +147,10 @@
 $(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 $@)
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -1195,23 +1195,25 @@
             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}
--- a/build/make/rtcd.pl
+++ b/build/make/rtcd.pl
@@ -315,6 +315,13 @@
 
 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;
@@ -321,8 +328,13 @@
 #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 @@
   &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/);
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -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 @@
   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;
--- /dev/null
+++ b/vpx_ports/mips.h
@@ -1,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_
--- /dev/null
+++ b/vpx_ports/mips_cpudetect.c
@@ -1,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
--- a/vpx_ports/vpx_ports.mk
+++ b/vpx_ports/vpx_ports.mk
@@ -42,6 +42,9 @@
 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