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

Reply via email to