ref: 42a1b310e14fcf0560bbb76afdc721a0583d6b6b
parent: 6a86492adf622b32643c7ee350afb58d2379b156
parent: 51289302ab02d81c17d3f15bbfb9a22eef4a36c1
author: Johann Koenig <johannkoenig@google.com>
date: Wed Mar 8 17:38:21 EST 2017
Merge "Add support for POWER8/VSX"
--- a/build/make/Makefile
+++ b/build/make/Makefile
@@ -124,6 +124,7 @@
CFLAGS += -mstackrealign
endif
+# x86[_64]
$(BUILD_PFX)%_mmx.c.d: CFLAGS += -mmmx
$(BUILD_PFX)%_mmx.c.o: CFLAGS += -mmmx
$(BUILD_PFX)%_sse2.c.d: CFLAGS += -msse2
@@ -138,6 +139,10 @@
$(BUILD_PFX)%_avx.c.o: CFLAGS += -mavx
$(BUILD_PFX)%_avx2.c.d: CFLAGS += -mavx2
$(BUILD_PFX)%_avx2.c.o: CFLAGS += -mavx2
+
+# POWER
+$(BUILD_PFX)%_vsx.c.d: CFLAGS += -mvsx
+$(BUILD_PFX)%_vsx.c.o: CFLAGS += -mvsx
$(BUILD_PFX)%.c.d: %.c
$(if $(quiet),@echo " [DEP] $@")
--- a/build/make/configure.sh
+++ b/build/make/configure.sh
@@ -697,6 +697,9 @@
*sparc*)
tgt_isa=sparc
;;
+ power*)
+ tgt_isa=ppc
+ ;;
esac
# detect tgt_os
@@ -782,6 +785,9 @@
mips*)
enable_feature mips
;;
+ ppc*)
+ enable_feature ppc
+ ;;
esac
# PIC is probably what we want when building shared libs
@@ -1158,6 +1164,11 @@
check_add_cflags -march=${tgt_isa}
check_add_asflags -march=${tgt_isa}
check_add_asflags -KPIC
+ ;;
+ ppc*)
+ link_with_cc=gcc
+ setup_gnu_toolchain
+ check_gcc_machine_option "vsx"
;;
x86*)
case ${tgt_os} in
--- a/build/make/rtcd.pl
+++ b/build/make/rtcd.pl
@@ -335,6 +335,36 @@
common_bottom;
}
+sub ppc() {
+ 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/ppc.h"
+static void setup_rtcd_internal(void)
+{
+ int flags = ppc_simd_caps();
+ (void)flags;
+EOF
+
+ set_function_pointers("c", @ALL_ARCHS);
+
+ print <<EOF;
+}
+#endif
+EOF
+ common_bottom;
+}
+
sub unoptimized() {
determine_indirection "c";
common_top;
@@ -390,6 +420,9 @@
} elsif ($opts{arch} eq 'armv8' || $opts{arch} eq 'arm64' ) {
@ALL_ARCHS = filter(qw/neon/);
arm;
+} elsif ($opts{arch} eq 'ppc' ) {
+ @ALL_ARCHS = filter(qw/vsx/);
+ ppc;
} else {
unoptimized;
}
--- a/configure
+++ b/configure
@@ -113,6 +113,9 @@
all_platforms="${all_platforms} armv8-linux-gcc"
all_platforms="${all_platforms} mips32-linux-gcc"
all_platforms="${all_platforms} mips64-linux-gcc"
+all_platforms="${all_platforms} ppc-linux-gcc"
+all_platforms="${all_platforms} ppc64-linux-gcc"
+all_platforms="${all_platforms} ppc64le-linux-gcc"
all_platforms="${all_platforms} sparc-solaris-gcc"
all_platforms="${all_platforms} x86-android-gcc"
all_platforms="${all_platforms} x86-darwin8-gcc"
@@ -225,6 +228,7 @@
mips
x86
x86_64
+ ppc
"
ARCH_EXT_LIST_X86="
mmx
@@ -246,6 +250,8 @@
mips64
${ARCH_EXT_LIST_X86}
+
+ vsx
"
HAVE_LIST="
${ARCH_EXT_LIST}
--- a/vp8/common/generic/systemdependent.c
+++ b/vp8/common/generic/systemdependent.c
@@ -94,5 +94,7 @@
ctx->cpu_caps = arm_cpu_caps();
#elif ARCH_X86 || ARCH_X86_64
ctx->cpu_caps = x86_simd_caps();
+#elif ARCH_PPC
+ ctx->cpu_caps = ppc_simd_caps();
#endif
}
--- /dev/null
+++ b/vpx_ports/ppc.h
@@ -1,0 +1,29 @@
+/*
+ * Copyright (c) 2017 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_PPC_H_
+#define VPX_PORTS_PPC_H_
+#include <stdlib.h>
+
+#include "./vpx_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HAS_VSX 0x01
+
+int ppc_simd_caps(void);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // VPX_PORTS_PPC_H_
--- /dev/null
+++ b/vpx_ports/ppc_cpudetect.c
@@ -1,0 +1,80 @@
+/*
+ * Copyright (c) 2017 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 <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <asm/cputable.h>
+#include <linux/auxvec.h>
+
+#include "./vpx_config.h"
+#include "vpx_ports/ppc.h"
+
+#if CONFIG_RUNTIME_CPU_DETECT
+static int cpu_env_flags(int *flags) {
+ char *env;
+ env = getenv("VPX_SIMD_CAPS");
+ if (env && *env) {
+ *flags = (int)strtol(env, NULL, 0);
+ return 0;
+ }
+ *flags = 0;
+ return -1;
+}
+
+static int cpu_env_mask(void) {
+ char *env;
+ env = getenv("VPX_SIMD_CAPS_MASK");
+ return env && *env ? (int)strtol(env, NULL, 0) : ~0;
+}
+
+int ppc_simd_caps(void) {
+ int flags;
+ int mask;
+ int fd;
+ ssize_t count;
+ unsigned int i;
+ uint64_t buf[64];
+
+ // If VPX_SIMD_CAPS is set then allow only those capabilities.
+ if (!cpu_env_flags(&flags)) {
+ return flags;
+ }
+
+ mask = cpu_env_mask();
+
+ fd = open("/proc/self/auxv", O_RDONLY);
+ if (fd < 0) {
+ return 0;
+ }
+
+ while ((count = read(fd, buf, sizeof(buf))) > 0) {
+ for (i = 0; i < (count / sizeof(*buf)); i += 2) {
+ if (buf[i] == AT_HWCAP) {
+#if HAVE_VSX
+ if (buf[i + 1] & PPC_FEATURE_HAS_VSX) {
+ flags |= HAS_VSX;
+ }
+#endif // HAVE_VSX
+ goto out_close;
+ } else if (buf[i] == AT_NULL) {
+ goto out_close;
+ }
+ }
+ }
+out_close:
+ close(fd);
+ return flags & mask;
+}
+#else
+// If there is no RTCD the function pointers are not used and can not be
+// changed.
+int ppc_simd_caps(void) { return 0; }
+#endif // CONFIG_RUNTIME_CPU_DETECT
--- a/vpx_ports/vpx_ports.mk
+++ b/vpx_ports/vpx_ports.mk
@@ -25,3 +25,6 @@
PORTS_SRCS-$(ARCH_ARM) += arm_cpudetect.c
PORTS_SRCS-$(ARCH_ARM) += arm.h
+
+PORTS_SRCS-$(ARCH_PPC) += ppc_cpudetect.c
+PORTS_SRCS-$(ARCH_PPC) += ppc.h