On 2014-01-03 20:03:16 +0200, Martin Storsjö wrote:
> This is pretty much based on the same test for XMM registers.
> ---
> configure | 13 ++++++++
> libavcodec/arm/Makefile | 1 +
> libavcodec/arm/neontest.c | 79
> +++++++++++++++++++++++++++++++++++++++++++++++
> libavutil/arm/neontest.h | 65 ++++++++++++++++++++++++++++++++++++++
> 4 files changed, 158 insertions(+)
> create mode 100644 libavcodec/arm/neontest.c
> create mode 100644 libavutil/arm/neontest.h
>
> diff --git a/configure b/configure
> index 49f1e73..c1d4cfb 100755
> --- a/configure
> +++ b/configure
> @@ -286,6 +286,8 @@ Developer options (useful when working on Libav itself):
> --enable-extra-warnings enable more compiler warnings
> --samples=PATH location of test samples for FATE, if not set use
> \$LIBAV_SAMPLES at make invocation time.
> + --enable-neon-clobber-test check NEON registers for clobbering (should be
> + used only for debugging purposes)
> --enable-xmm-clobber-test check XMM registers for clobbering (Win64-only;
> should be used only for debugging purposes)
> --enable-random randomly enable/disable components
> @@ -1165,6 +1167,7 @@ CONFIG_LIST="
> lzo
> mdct
> memalign_hack
> + neon_clobber_test
> network
> nonfree
> pod2man
> @@ -4046,6 +4049,16 @@ test_ldflags -Wl,-Bsymbolic && append SHFLAGS
> -Wl,-Bsymbolic
> # -wN '..@*' is more selective than -x, but not available everywhere.
> check_stripflags -wN \'..@*\' || check_stripflags -x || strip='true'
>
> +enabled neon_clobber_test &&
> + check_ldflags -Wl,--wrap,avcodec_open2 \
> + -Wl,--wrap,avcodec_decode_audio4 \
> + -Wl,--wrap,avcodec_decode_video2 \
> + -Wl,--wrap,avcodec_decode_subtitle2 \
> + -Wl,--wrap,avcodec_encode_audio2 \
> + -Wl,--wrap,avcodec_encode_video2 \
> + -Wl,--wrap,avcodec_encode_subtitle ||
> + disable neon_clobber_test
> +
> enabled xmm_clobber_test &&
> check_ldflags -Wl,--wrap,avcodec_open2 \
> -Wl,--wrap,avcodec_decode_audio4 \
> diff --git a/libavcodec/arm/Makefile b/libavcodec/arm/Makefile
> index 277abd9..8bdccbd 100644
> --- a/libavcodec/arm/Makefile
> +++ b/libavcodec/arm/Makefile
> @@ -23,6 +23,7 @@ OBJS-$(CONFIG_HPELDSP) +=
> arm/hpeldsp_init_arm.o \
> arm/hpeldsp_arm.o
> OBJS-$(CONFIG_MPEGAUDIODSP) += arm/mpegaudiodsp_init_arm.o
> OBJS-$(CONFIG_MPEGVIDEO) += arm/mpegvideo_arm.o
> +OBJS-$(CONFIG_NEON_CLOBBER_TEST) += arm/neontest.o
> OBJS-$(CONFIG_VC1_DECODER) += arm/vc1dsp_init_arm.o
> OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_init_arm.o
> OBJS-$(CONFIG_VP3DSP) += arm/vp3dsp_init_arm.o
> diff --git a/libavcodec/arm/neontest.c b/libavcodec/arm/neontest.c
> new file mode 100644
> index 0000000..b77bcd7
> --- /dev/null
> +++ b/libavcodec/arm/neontest.c
> @@ -0,0 +1,79 @@
> +/*
> + * check NEON registers for clobbers
> + * Copyright (c) 2013 Martin Storsjo
> + *
> + * 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 "libavcodec/avcodec.h"
> +#include "libavutil/arm/neontest.h"
> +
> +wrap(avcodec_open2(AVCodecContext *avctx,
> + AVCodec *codec,
> + AVDictionary **options))
> +{
> + testneonclobbers(avcodec_open2, avctx, codec, options);
> +}
> +
> +wrap(avcodec_decode_audio4(AVCodecContext *avctx,
> + AVFrame *frame,
> + int *got_frame_ptr,
> + AVPacket *avpkt))
> +{
> + testneonclobbers(avcodec_decode_audio4, avctx, frame,
> + got_frame_ptr, avpkt);
> +}
> +
> +wrap(avcodec_decode_video2(AVCodecContext *avctx,
> + AVFrame *picture,
> + int *got_picture_ptr,
> + AVPacket *avpkt))
> +{
> + testneonclobbers(avcodec_decode_video2, avctx, picture,
> + got_picture_ptr, avpkt);
> +}
> +
> +wrap(avcodec_decode_subtitle2(AVCodecContext *avctx,
> + AVSubtitle *sub,
> + int *got_sub_ptr,
> + AVPacket *avpkt))
> +{
> + testneonclobbers(avcodec_decode_subtitle2, avctx, sub,
> + got_sub_ptr, avpkt);
> +}
> +
> +wrap(avcodec_encode_audio2(AVCodecContext *avctx,
> + AVPacket *avpkt,
> + const AVFrame *frame,
> + int *got_packet_ptr))
> +{
> + testneonclobbers(avcodec_encode_audio2, avctx, avpkt, frame,
> + got_packet_ptr);
> +}
> +
> +wrap(avcodec_encode_subtitle(AVCodecContext *avctx,
> + uint8_t *buf, int buf_size,
> + const AVSubtitle *sub))
> +{
> + testneonclobbers(avcodec_encode_subtitle, avctx, buf, buf_size, sub);
> +}
> +
> +wrap(avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
> + const AVFrame *frame, int *got_packet_ptr))
> +{
> + testneonclobbers(avcodec_encode_video2, avctx, avpkt, frame,
> got_packet_ptr);
> +}
> diff --git a/libavutil/arm/neontest.h b/libavutil/arm/neontest.h
> new file mode 100644
> index 0000000..9907e24
> --- /dev/null
> +++ b/libavutil/arm/neontest.h
> @@ -0,0 +1,65 @@
> +/*
> + * check NEON registers for clobbering
> + * Copyright (c) 2008 Ramiro Polla <[email protected]>
> + * Copyright (c) 2013 Martin Storsjo
> + *
> + * 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 <inttypes.h>
> +#include <stdint.h>
> +#include <stdlib.h>
> +#include <stdarg.h>
> +#include <string.h>
> +
> +#include "libavutil/bswap.h"
> +
> +#define storeneonregs(mem) \
> + __asm__ volatile( \
> + "vstm %0, {q4-q7}\n\t" \
vstm needs double-word registers, gas probably expands that but see
below
> + :: "r"(mem) : "memory")
> +
> +#define testneonclobbers(func, ctx, ...) \
> + uint64_t neon[2][4][2]; \
uint64_t neon[2][8] would match the double word registers and makes no
assumptions on the array memory layout.
> + int ret; \
> + storeneonregs(neon[0]); \
> + ret = __real_ ## func(ctx, __VA_ARGS__); \
> + storeneonregs(neon[1]); \
> + if (memcmp(neon[0], neon[1], sizeof(neon[0]))) { \
> + int i; \
> + av_log(ctx, AV_LOG_ERROR, \
> + "NEON REGS CLOBBERED IN %s!\n", #func); \
> + for (i = 0; i < 4; i ++) \
> + if (neon[0][i][0] != neon[1][i][0] || \
> + neon[0][i][1] != neon[1][i][1]) { \
> + av_log(ctx, AV_LOG_ERROR, \
> + "q%d = %016"PRIx64"%016"PRIx64"\n", \
> + 4 + i, av_bswap64(neon[0][i][0]), \
> + av_bswap64(neon[0][i][1])); \
> + av_log(ctx, AV_LOG_ERROR, \
> + " -> %016"PRIx64"%016"PRIx64"\n", \
> + av_bswap64(neon[1][i][0]), \
> + av_bswap64(neon[1][i][1])); \
> + } \
> + abort(); \
> + } \
> + return ret
> +
> +#define wrap(func) \
> +int __real_ ## func; \
> +int __wrap_ ## func; \
> +int __wrap_ ## func
otherwise ok
Janne
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel