annotate ffmpeg/libavcodec/x86/cabac.h @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
yading@10 3 *
yading@10 4 * This file is part of Libav.
yading@10 5 *
yading@10 6 * Libav is free software; you can redistribute it and/or
yading@10 7 * modify it under the terms of the GNU Lesser General Public
yading@10 8 * License as published by the Free Software Foundation; either
yading@10 9 * version 2.1 of the License, or (at your option) any later version.
yading@10 10 *
yading@10 11 * Libav is distributed in the hope that it will be useful,
yading@10 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 14 * Lesser General Public License for more details.
yading@10 15 *
yading@10 16 * You should have received a copy of the GNU Lesser General Public
yading@10 17 * License along with Libav; if not, write to the Free Software
yading@10 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 19 */
yading@10 20
yading@10 21 #ifndef AVCODEC_X86_CABAC_H
yading@10 22 #define AVCODEC_X86_CABAC_H
yading@10 23
yading@10 24 #include "libavcodec/cabac.h"
yading@10 25 #include "libavutil/attributes.h"
yading@10 26 #include "libavutil/x86/asm.h"
yading@10 27 #include "libavutil/internal.h"
yading@10 28 #include "config.h"
yading@10 29
yading@10 30 #if HAVE_INLINE_ASM
yading@10 31
yading@10 32 #ifdef BROKEN_RELOCATIONS
yading@10 33 #define TABLES_ARG , "r"(tables)
yading@10 34
yading@10 35 #if HAVE_FAST_CMOV
yading@10 36 #define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \
yading@10 37 "cmp "low" , "tmp" \n\t"\
yading@10 38 "cmova %%ecx , "range" \n\t"\
yading@10 39 "sbb %%rcx , %%rcx \n\t"\
yading@10 40 "and %%ecx , "tmp" \n\t"\
yading@10 41 "xor %%rcx , "retq" \n\t"\
yading@10 42 "sub "tmp" , "low" \n\t"
yading@10 43 #else /* HAVE_FAST_CMOV */
yading@10 44 #define BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \
yading@10 45 /* P4 Prescott has crappy cmov,sbb,64bit shift so avoid them */ \
yading@10 46 "sub "low" , "tmp" \n\t"\
yading@10 47 "sar $31 , "tmp" \n\t"\
yading@10 48 "sub %%ecx , "range" \n\t"\
yading@10 49 "and "tmp" , "range" \n\t"\
yading@10 50 "add %%ecx , "range" \n\t"\
yading@10 51 "shl $17 , %%ecx \n\t"\
yading@10 52 "and "tmp" , %%ecx \n\t"\
yading@10 53 "sub %%ecx , "low" \n\t"\
yading@10 54 "xor "tmp" , "ret" \n\t"\
yading@10 55 "movslq "ret" , "retq" \n\t"
yading@10 56 #endif /* HAVE_FAST_CMOV */
yading@10 57
yading@10 58 #define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \
yading@10 59 "movzbl "statep" , "ret" \n\t"\
yading@10 60 "mov "range" , "tmp" \n\t"\
yading@10 61 "and $0xC0 , "range" \n\t"\
yading@10 62 "lea ("ret", "range", 2), %%ecx \n\t"\
yading@10 63 "movzbl "lps_off"("tables", %%rcx), "range" \n\t"\
yading@10 64 "sub "range" , "tmp" \n\t"\
yading@10 65 "mov "tmp" , %%ecx \n\t"\
yading@10 66 "shl $17 , "tmp" \n\t"\
yading@10 67 BRANCHLESS_GET_CABAC_UPDATE(ret, retq, low, range, tmp) \
yading@10 68 "movzbl "norm_off"("tables", "rangeq"), %%ecx \n\t"\
yading@10 69 "shl %%cl , "range" \n\t"\
yading@10 70 "movzbl "mlps_off"+128("tables", "retq"), "tmp" \n\t"\
yading@10 71 "shl %%cl , "low" \n\t"\
yading@10 72 "mov "tmpbyte" , "statep" \n\t"\
yading@10 73 "test "lowword" , "lowword" \n\t"\
yading@10 74 "jnz 2f \n\t"\
yading@10 75 "mov "byte" , %%"REG_c" \n\t"\
yading@10 76 "add"OPSIZE" $2 , "byte" \n\t"\
yading@10 77 "movzwl (%%"REG_c") , "tmp" \n\t"\
yading@10 78 "lea -1("low") , %%ecx \n\t"\
yading@10 79 "xor "low" , %%ecx \n\t"\
yading@10 80 "shr $15 , %%ecx \n\t"\
yading@10 81 "bswap "tmp" \n\t"\
yading@10 82 "shr $15 , "tmp" \n\t"\
yading@10 83 "movzbl "norm_off"("tables", %%rcx), %%ecx \n\t"\
yading@10 84 "sub $0xFFFF , "tmp" \n\t"\
yading@10 85 "neg %%ecx \n\t"\
yading@10 86 "add $7 , %%ecx \n\t"\
yading@10 87 "shl %%cl , "tmp" \n\t"\
yading@10 88 "add "tmp" , "low" \n\t"\
yading@10 89 "2: \n\t"
yading@10 90
yading@10 91 #else /* BROKEN_RELOCATIONS */
yading@10 92 #define TABLES_ARG
yading@10 93 #define RIP_ARG
yading@10 94
yading@10 95 #if HAVE_FAST_CMOV
yading@10 96 #define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\
yading@10 97 "mov "tmp" , %%ecx \n\t"\
yading@10 98 "shl $17 , "tmp" \n\t"\
yading@10 99 "cmp "low" , "tmp" \n\t"\
yading@10 100 "cmova %%ecx , "range" \n\t"\
yading@10 101 "sbb %%ecx , %%ecx \n\t"\
yading@10 102 "and %%ecx , "tmp" \n\t"\
yading@10 103 "xor %%ecx , "ret" \n\t"\
yading@10 104 "sub "tmp" , "low" \n\t"
yading@10 105 #else /* HAVE_FAST_CMOV */
yading@10 106 #define BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp)\
yading@10 107 "mov "tmp" , %%ecx \n\t"\
yading@10 108 "shl $17 , "tmp" \n\t"\
yading@10 109 "sub "low" , "tmp" \n\t"\
yading@10 110 "sar $31 , "tmp" \n\t" /*lps_mask*/\
yading@10 111 "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\
yading@10 112 "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\
yading@10 113 "add %%ecx , "range" \n\t" /*new range*/\
yading@10 114 "shl $17 , %%ecx \n\t"\
yading@10 115 "and "tmp" , %%ecx \n\t"\
yading@10 116 "sub %%ecx , "low" \n\t"\
yading@10 117 "xor "tmp" , "ret" \n\t"
yading@10 118 #endif /* HAVE_FAST_CMOV */
yading@10 119
yading@10 120 #define BRANCHLESS_GET_CABAC(ret, retq, statep, low, lowword, range, rangeq, tmp, tmpbyte, byte, end, norm_off, lps_off, mlps_off, tables) \
yading@10 121 "movzbl "statep" , "ret" \n\t"\
yading@10 122 "mov "range" , "tmp" \n\t"\
yading@10 123 "and $0xC0 , "range" \n\t"\
yading@10 124 "movzbl "MANGLE(ff_h264_cabac_tables)"+"lps_off"("ret", "range", 2), "range" \n\t"\
yading@10 125 "sub "range" , "tmp" \n\t"\
yading@10 126 BRANCHLESS_GET_CABAC_UPDATE(ret, low, range, tmp) \
yading@10 127 "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"("range"), %%ecx \n\t"\
yading@10 128 "shl %%cl , "range" \n\t"\
yading@10 129 "movzbl "MANGLE(ff_h264_cabac_tables)"+"mlps_off"+128("ret"), "tmp" \n\t"\
yading@10 130 "shl %%cl , "low" \n\t"\
yading@10 131 "mov "tmpbyte" , "statep" \n\t"\
yading@10 132 "test "lowword" , "lowword" \n\t"\
yading@10 133 " jnz 2f \n\t"\
yading@10 134 "mov "byte" , %%"REG_c" \n\t"\
yading@10 135 "add"OPSIZE" $2 , "byte" \n\t"\
yading@10 136 "movzwl (%%"REG_c") , "tmp" \n\t"\
yading@10 137 "lea -1("low") , %%ecx \n\t"\
yading@10 138 "xor "low" , %%ecx \n\t"\
yading@10 139 "shr $15 , %%ecx \n\t"\
yading@10 140 "bswap "tmp" \n\t"\
yading@10 141 "shr $15 , "tmp" \n\t"\
yading@10 142 "movzbl "MANGLE(ff_h264_cabac_tables)"+"norm_off"(%%ecx), %%ecx \n\t"\
yading@10 143 "sub $0xFFFF , "tmp" \n\t"\
yading@10 144 "neg %%ecx \n\t"\
yading@10 145 "add $7 , %%ecx \n\t"\
yading@10 146 "shl %%cl , "tmp" \n\t"\
yading@10 147 "add "tmp" , "low" \n\t"\
yading@10 148 "2: \n\t"
yading@10 149
yading@10 150 #endif /* BROKEN_RELOCATIONS */
yading@10 151
yading@10 152
yading@10 153 #if HAVE_7REGS && !(defined(__i386) && defined(__clang__) && (__clang_major__<2 || (__clang_major__==2 && __clang_minor__<10)))\
yading@10 154 && !( !defined(__clang__) && defined(__llvm__) && __GNUC__==4 && __GNUC_MINOR__==2 && __GNUC_PATCHLEVEL__<=1)
yading@10 155 #define get_cabac_inline get_cabac_inline_x86
yading@10 156 static av_always_inline int get_cabac_inline_x86(CABACContext *c,
yading@10 157 uint8_t *const state)
yading@10 158 {
yading@10 159 int bit, tmp;
yading@10 160 #ifdef BROKEN_RELOCATIONS
yading@10 161 void *tables;
yading@10 162
yading@10 163 __asm__ volatile(
yading@10 164 "lea "MANGLE(ff_h264_cabac_tables)", %0 \n\t"
yading@10 165 : "=&r"(tables)
yading@10 166 );
yading@10 167 #endif
yading@10 168
yading@10 169 __asm__ volatile(
yading@10 170 BRANCHLESS_GET_CABAC("%0", "%q0", "(%4)", "%1", "%w1",
yading@10 171 "%2", "%q2", "%3", "%b3",
yading@10 172 "%c6(%5)", "%c7(%5)",
yading@10 173 AV_STRINGIFY(H264_NORM_SHIFT_OFFSET),
yading@10 174 AV_STRINGIFY(H264_LPS_RANGE_OFFSET),
yading@10 175 AV_STRINGIFY(H264_MLPS_STATE_OFFSET),
yading@10 176 "%8")
yading@10 177 : "=&r"(bit), "=&r"(c->low), "=&r"(c->range), "=&q"(tmp)
yading@10 178 : "r"(state), "r"(c),
yading@10 179 "i"(offsetof(CABACContext, bytestream)),
yading@10 180 "i"(offsetof(CABACContext, bytestream_end))
yading@10 181 TABLES_ARG
yading@10 182 ,"1"(c->low), "2"(c->range)
yading@10 183 : "%"REG_c, "memory"
yading@10 184 );
yading@10 185 return bit & 1;
yading@10 186 }
yading@10 187 #endif /* HAVE_7REGS */
yading@10 188
yading@10 189 #define get_cabac_bypass_sign get_cabac_bypass_sign_x86
yading@10 190 static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val)
yading@10 191 {
yading@10 192 x86_reg tmp;
yading@10 193 __asm__ volatile(
yading@10 194 "movl %c6(%2), %k1 \n\t"
yading@10 195 "movl %c3(%2), %%eax \n\t"
yading@10 196 "shl $17, %k1 \n\t"
yading@10 197 "add %%eax, %%eax \n\t"
yading@10 198 "sub %k1, %%eax \n\t"
yading@10 199 "cltd \n\t"
yading@10 200 "and %%edx, %k1 \n\t"
yading@10 201 "add %k1, %%eax \n\t"
yading@10 202 "xor %%edx, %%ecx \n\t"
yading@10 203 "sub %%edx, %%ecx \n\t"
yading@10 204 "test %%ax, %%ax \n\t"
yading@10 205 "jnz 1f \n\t"
yading@10 206 "mov %c4(%2), %1 \n\t"
yading@10 207 "subl $0xFFFF, %%eax \n\t"
yading@10 208 "movzwl (%1), %%edx \n\t"
yading@10 209 "bswap %%edx \n\t"
yading@10 210 "shrl $15, %%edx \n\t"
yading@10 211 "add $2, %1 \n\t"
yading@10 212 "addl %%edx, %%eax \n\t"
yading@10 213 "mov %1, %c4(%2) \n\t"
yading@10 214 "1: \n\t"
yading@10 215 "movl %%eax, %c3(%2) \n\t"
yading@10 216
yading@10 217 : "+c"(val), "=&r"(tmp)
yading@10 218 : "r"(c),
yading@10 219 "i"(offsetof(CABACContext, low)),
yading@10 220 "i"(offsetof(CABACContext, bytestream)),
yading@10 221 "i"(offsetof(CABACContext, bytestream_end)),
yading@10 222 "i"(offsetof(CABACContext, range))
yading@10 223 : "%eax", "%edx", "memory"
yading@10 224 );
yading@10 225 return val;
yading@10 226 }
yading@10 227
yading@10 228 #endif /* HAVE_INLINE_ASM */
yading@10 229 #endif /* AVCODEC_X86_CABAC_H */