diff --git a/build/make/Makefile b/build/make/Makefile index cba605786..0d29609ff 100644 --- a/build/make/Makefile +++ b/build/make/Makefile @@ -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 $@) diff --git a/build/make/configure.sh b/build/make/configure.sh index ac60f5082..dcfdfe1d2 100644 --- a/build/make/configure.sh +++ b/build/make/configure.sh @@ -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*) diff --git a/build/make/rtcd.pl b/build/make/rtcd.pl index 9e746c46d..58700895f 100755 --- a/build/make/rtcd.pl +++ b/build/make/rtcd.pl @@ -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 < +#include +#include +#include +#include + +#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 diff --git a/vpx_ports/vpx_ports.mk b/vpx_ports/vpx_ports.mk index 36b14936d..fc0a783b7 100644 --- a/vpx_ports/vpx_ports.mk +++ b/vpx_ports/vpx_ports.mk @@ -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