aarch64: add cpuflags support for NEON and VFP

NEON and VFP are currently mandatory for all ARMv8 profiles. Both are
handled as extensions as far as cpuflags are concerned. This is
consistent with handling x86_64 which always has SSE2, but still
handles it as an extension.
This commit is contained in:
Janne Grunau 2013-12-10 20:13:32 +01:00
parent 1e9265cd8f
commit b7b17ed66e
7 changed files with 150 additions and 7 deletions

17
configure vendored
View File

@ -1543,8 +1543,8 @@ CMDLINE_APPEND="
armv5te_deps="arm" armv5te_deps="arm"
armv6_deps="arm" armv6_deps="arm"
armv6t2_deps="arm" armv6t2_deps="arm"
neon_deps="arm" neon_deps_any="aarch64 arm"
vfp_deps="arm" vfp_deps_any="aarch64 arm"
vfpv3_deps="vfp" vfpv3_deps="vfp"
map 'eval ${v}_inline_deps=inline_asm' $ARCH_EXT_LIST_ARM map 'eval ${v}_inline_deps=inline_asm' $ARCH_EXT_LIST_ARM
@ -3596,7 +3596,14 @@ od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
check_inline_asm inline_asm_labels '"1:\n"' check_inline_asm inline_asm_labels '"1:\n"'
if enabled alpha; then if enabled aarch64; then
# internal assembler in clang 3.3 does not support this instruction
enabled neon && check_insn neon 'ext v0.8B, v0.8B, v1.8B, #1'
enabled vfp && check_insn vfp 'fmadd d0, d0, d1, d2'
map 'enabled_any ${v}_external ${v}_inline || disable $v' $ARCH_EXT_LIST_ARM
elif enabled alpha; then
check_cflags -mieee check_cflags -mieee
@ -4250,6 +4257,10 @@ if enabled x86; then
echo "EBX available ${ebx_available-no}" echo "EBX available ${ebx_available-no}"
echo "EBP available ${ebp_available-no}" echo "EBP available ${ebp_available-no}"
fi fi
if enabled aarch64; then
echo "NEON enabled ${neon-no}"
echo "VFP enabled ${vfp-no}"
fi
if enabled arm; then if enabled arm; then
echo "ARMv5TE enabled ${armv5te-no}" echo "ARMv5TE enabled ${armv5te-no}"
echo "ARMv6 enabled ${armv6-no}" echo "ARMv6 enabled ${armv6-no}"

View File

@ -0,0 +1 @@
OBJS += aarch64/cpu.o

63
libavutil/aarch64/asm.S Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2008 Mans Rullgard <mans@mansr.com>
*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "config.h"
#ifdef __ELF__
# define ELF
#else
# define ELF //
#endif
.macro function name, export=0, align=2
.macro endfunc
ELF .size \name, . - \name
.endfunc
.purgem endfunc
.endm
.text
.align \align
.if \export
.global EXTERN_ASM\name
EXTERN_ASM\name:
.endif
ELF .type \name, %function
.func \name
\name:
.endm
.macro const name, align=2
.macro endconst
ELF .size \name, . - \name
.purgem endconst
.endm
.section .rodata
.align \align
\name:
.endm
.macro movrel rd, val
#if CONFIG_PIC
adrp \rd, #:pg_hi21:\val
add \rd, \rd, #:lo12:\val
#else
ldr \rd, =\val
#endif
.endm

27
libavutil/aarch64/cpu.c Normal file
View File

@ -0,0 +1,27 @@
/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "libavutil/cpu.h"
#include "libavutil/cpu_internal.h"
#include "config.h"
int ff_get_cpu_flags_aarch64(void)
{
return AV_CPU_FLAG_NEON * HAVE_NEON |
AV_CPU_FLAG_VFP * HAVE_VFP;
}

29
libavutil/aarch64/cpu.h Normal file
View File

@ -0,0 +1,29 @@
/*
* This file is part of Libav.
*
* Libav is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Libav is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef AVUTIL_AARCH64_CPU_H
#define AVUTIL_AARCH64_CPU_H
#include "config.h"
#include "libavutil/cpu.h"
#include "libavutil/cpu_internal.h"
#define have_neon(flags) CPUEXT(flags, NEON)
#define have_vfp(flags) CPUEXT(flags, VFP)
#endif /* AVUTIL_AARCH64_CPU_H */

View File

@ -51,9 +51,14 @@ int av_get_cpu_flags(void)
if (checked) if (checked)
return flags; return flags;
if (ARCH_ARM) flags = ff_get_cpu_flags_arm(); if (ARCH_AARCH64)
if (ARCH_PPC) flags = ff_get_cpu_flags_ppc(); flags = ff_get_cpu_flags_aarch64();
if (ARCH_X86) flags = ff_get_cpu_flags_x86(); if (ARCH_ARM)
flags = ff_get_cpu_flags_arm();
if (ARCH_PPC)
flags = ff_get_cpu_flags_ppc();
if (ARCH_X86)
flags = ff_get_cpu_flags_x86();
flags &= cpuflags_mask; flags &= cpuflags_mask;
checked = 1; checked = 1;
@ -114,6 +119,9 @@ int av_parse_cpu_flags(const char *s)
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
{ "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
#elif ARCH_AARCH64
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
#endif #endif
{ NULL }, { NULL },
}; };
@ -170,7 +178,10 @@ static const struct {
int flag; int flag;
const char *name; const char *name;
} cpu_flag_tab[] = { } cpu_flag_tab[] = {
#if ARCH_ARM #if ARCH_AARCH64
{ AV_CPU_FLAG_NEON, "neon" },
{ AV_CPU_FLAG_VFP, "vfp" },
#elif ARCH_ARM
{ AV_CPU_FLAG_ARMV5TE, "armv5te" }, { AV_CPU_FLAG_ARMV5TE, "armv5te" },
{ AV_CPU_FLAG_ARMV6, "armv6" }, { AV_CPU_FLAG_ARMV6, "armv6" },
{ AV_CPU_FLAG_ARMV6T2, "armv6t2" }, { AV_CPU_FLAG_ARMV6T2, "armv6t2" },

View File

@ -26,6 +26,7 @@
#define CPUEXT(flags, cpuext) CPUEXT_SUFFIX(flags, , cpuext) #define CPUEXT(flags, cpuext) CPUEXT_SUFFIX(flags, , cpuext)
int ff_get_cpu_flags_aarch64(void);
int ff_get_cpu_flags_arm(void); int ff_get_cpu_flags_arm(void);
int ff_get_cpu_flags_ppc(void); int ff_get_cpu_flags_ppc(void);
int ff_get_cpu_flags_x86(void); int ff_get_cpu_flags_x86(void);