shithub: libvpx

Download patch

ref: ebbe5b82a052a316b0df52a5109071f512b7d23c
parent: 53747dfe65eaf670a7192f55117f3bf1e0280743
parent: ea6562f2fcd8ea6baa946eaad69cbb5aec5dd278
author: James Zern <jzern@google.com>
date: Tue Aug 18 22:49:29 EDT 2020

Merge "Refine MMI & MSA detection for mips"

--- 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