* qatar/master: arm: Add an option for making sure NEON registers aren't clobbered Conflicts: configure Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n2.2-rc1
| @@ -350,6 +350,8 @@ Developer options (useful when working on FFmpeg itself): | |||
| --enable-ftrapv Trap arithmetic overflows | |||
| --samples=PATH location of test samples for FATE, if not set use | |||
| \$FATE_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 | |||
| @@ -1371,6 +1373,7 @@ CONFIG_LIST=" | |||
| mdct | |||
| memalign_hack | |||
| memory_poisoning | |||
| neon_clobber_test | |||
| network | |||
| nonfree | |||
| pic | |||
| @@ -4629,6 +4632,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 | |||
| 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 \ | |||
| @@ -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 | |||
| @@ -0,0 +1,79 @@ | |||
| /* | |||
| * check NEON registers for clobbers | |||
| * Copyright (c) 2013 Martin Storsjo | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg 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. | |||
| * | |||
| * FFmpeg 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 FFmpeg; 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); | |||
| } | |||
| @@ -0,0 +1,62 @@ | |||
| /* | |||
| * check NEON registers for clobbering | |||
| * Copyright (c) 2008 Ramiro Polla <ramiro.polla@gmail.com> | |||
| * Copyright (c) 2013 Martin Storsjo | |||
| * | |||
| * This file is part of FFmpeg. | |||
| * | |||
| * FFmpeg 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. | |||
| * | |||
| * FFmpeg 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 FFmpeg; 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, {d8-d15}\n\t" \ | |||
| :: "r"(mem) : "memory") | |||
| #define testneonclobbers(func, ctx, ...) \ | |||
| uint64_t neon[2][8]; \ | |||
| 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 < 8; i ++) \ | |||
| if (neon[0][i] != neon[1][i]) { \ | |||
| av_log(ctx, AV_LOG_ERROR, \ | |||
| "d%-2d = %016"PRIx64"\n", \ | |||
| 8 + i, av_bswap64(neon[0][i])); \ | |||
| av_log(ctx, AV_LOG_ERROR, \ | |||
| " -> %016"PRIx64"\n", \ | |||
| av_bswap64(neon[1][i])); \ | |||
| } \ | |||
| abort(); \ | |||
| } \ | |||
| return ret | |||
| #define wrap(func) \ | |||
| int __real_ ## func; \ | |||
| int __wrap_ ## func; \ | |||
| int __wrap_ ## func | |||