Add support for POWER8/VSX

Add ppc, ppc64 and ppc64le on all_platforms and ARCH_LIST

Add VSX flags and check for -mvsx

Define empty setup_rtcd_internal

Add Altivec detection based on:
http://freevec.org/function/altivec_runtime_detection_linux

Detect VSX at runtime when enabled

Change-Id: I304f4d8c5fee0ff19b6483cd2e9cc50d6ddec472
Signed-off-by: Rafael de Lucena Valle <rafaeldelucena@gmail.com>
This commit is contained in:
Rafael de Lucena Valle 2016-10-19 22:21:09 -02:00 committed by Johann Koenig
parent 2fa710aa6d
commit 51289302ab
8 changed files with 169 additions and 0 deletions

View File

@ -124,6 +124,7 @@ ifeq ($(TOOLCHAIN), x86-os2-gcc)
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
@ -139,6 +140,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] $@")
$(qexec)mkdir -p $(dir $@)

View File

@ -697,6 +697,9 @@ process_common_toolchain() {
*sparc*)
tgt_isa=sparc
;;
power*)
tgt_isa=ppc
;;
esac
# detect tgt_os
@ -782,6 +785,9 @@ process_common_toolchain() {
mips*)
enable_feature mips
;;
ppc*)
enable_feature ppc
;;
esac
# PIC is probably what we want when building shared libs
@ -1159,6 +1165,11 @@ EOF
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
win*)

View File

@ -335,6 +335,36 @@ EOF
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 @@ if ($opts{arch} eq 'x86') {
} 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;
}

6
configure vendored
View File

@ -113,6 +113,9 @@ all_platforms="${all_platforms} armv7s-darwin-gcc"
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 @@ ARCH_LIST="
mips
x86
x86_64
ppc
"
ARCH_EXT_LIST_X86="
mmx
@ -246,6 +250,8 @@ ARCH_EXT_LIST="
mips64
${ARCH_EXT_LIST_X86}
vsx
"
HAVE_LIST="
${ARCH_EXT_LIST}

View File

@ -94,5 +94,7 @@ void vp8_machine_specific_config(VP8_COMMON *ctx) {
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
}

29
vpx_ports/ppc.h Normal file
View File

@ -0,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_

80
vpx_ports/ppc_cpudetect.c Normal file
View File

@ -0,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

View File

@ -25,3 +25,6 @@ endif
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