cabac: remove #if 0 cascade under never-set #ifdef ARCH_X86_DISABLED
[ffmpeg.git] / libavcodec / cabac.h
1 /*
2  * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
3  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * @file
24  * Context Adaptive Binary Arithmetic Coder.
25  */
26
27 #ifndef AVCODEC_CABAC_H
28 #define AVCODEC_CABAC_H
29
30 #include "put_bits.h"
31
32 //#undef NDEBUG
33 #include <assert.h>
34 #include "libavutil/x86_cpu.h"
35
36 #define CABAC_BITS 16
37 #define CABAC_MASK ((1<<CABAC_BITS)-1)
38 #define BRANCHLESS_CABAC_DECODER 1
39
40 typedef struct CABACContext{
41     int low;
42     int range;
43     int outstanding_count;
44 #ifdef STRICT_LIMITS
45     int symCount;
46 #endif
47     const uint8_t *bytestream_start;
48     const uint8_t *bytestream;
49     const uint8_t *bytestream_end;
50     PutBitContext pb;
51 }CABACContext;
52
53 extern uint8_t ff_h264_mlps_state[4*64];
54 extern uint8_t ff_h264_lps_range[4*2*64];  ///< rangeTabLPS
55 extern uint8_t ff_h264_mps_state[2*64];     ///< transIdxMPS
56 extern uint8_t ff_h264_lps_state[2*64];     ///< transIdxLPS
57 extern const uint8_t ff_h264_norm_shift[512];
58
59
60 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
61 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
62 void ff_init_cabac_states(CABACContext *c);
63
64
65 static inline void put_cabac_bit(CABACContext *c, int b){
66     put_bits(&c->pb, 1, b);
67     for(;c->outstanding_count; c->outstanding_count--){
68         put_bits(&c->pb, 1, 1-b);
69     }
70 }
71
72 static inline void renorm_cabac_encoder(CABACContext *c){
73     while(c->range < 0x100){
74         //FIXME optimize
75         if(c->low<0x100){
76             put_cabac_bit(c, 0);
77         }else if(c->low<0x200){
78             c->outstanding_count++;
79             c->low -= 0x100;
80         }else{
81             put_cabac_bit(c, 1);
82             c->low -= 0x200;
83         }
84
85         c->range+= c->range;
86         c->low += c->low;
87     }
88 }
89
90 #ifdef TEST
91 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
92     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
93
94     if(bit == ((*state)&1)){
95         c->range -= RangeLPS;
96         *state= ff_h264_mps_state[*state];
97     }else{
98         c->low += c->range - RangeLPS;
99         c->range = RangeLPS;
100         *state= ff_h264_lps_state[*state];
101     }
102
103     renorm_cabac_encoder(c);
104
105 #ifdef STRICT_LIMITS
106     c->symCount++;
107 #endif
108 }
109
110 static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
111     assert(c->range > RangeLPS);
112
113     if(!bit){
114         c->range -= RangeLPS;
115     }else{
116         c->low += c->range - RangeLPS;
117         c->range = RangeLPS;
118     }
119
120     renorm_cabac_encoder(c);
121
122 #ifdef STRICT_LIMITS
123     c->symCount++;
124 #endif
125 }
126
127 /**
128  * @param bit 0 -> write zero bit, !=0 write one bit
129  */
130 static void put_cabac_bypass(CABACContext *c, int bit){
131     c->low += c->low;
132
133     if(bit){
134         c->low += c->range;
135     }
136 //FIXME optimize
137     if(c->low<0x200){
138         put_cabac_bit(c, 0);
139     }else if(c->low<0x400){
140         c->outstanding_count++;
141         c->low -= 0x200;
142     }else{
143         put_cabac_bit(c, 1);
144         c->low -= 0x400;
145     }
146
147 #ifdef STRICT_LIMITS
148     c->symCount++;
149 #endif
150 }
151
152 /**
153  *
154  * @return the number of bytes written
155  */
156 static int put_cabac_terminate(CABACContext *c, int bit){
157     c->range -= 2;
158
159     if(!bit){
160         renorm_cabac_encoder(c);
161     }else{
162         c->low += c->range;
163         c->range= 2;
164
165         renorm_cabac_encoder(c);
166
167         assert(c->low <= 0x1FF);
168         put_cabac_bit(c, c->low>>9);
169         put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
170
171         flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
172     }
173
174 #ifdef STRICT_LIMITS
175     c->symCount++;
176 #endif
177
178     return (put_bits_count(&c->pb)+7)>>3;
179 }
180
181 /**
182  * put (truncated) unary binarization.
183  */
184 static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
185     int i;
186
187     assert(v <= max);
188
189 #if 1
190     for(i=0; i<v; i++){
191         put_cabac(c, state, 1);
192         if(i < max_index) state++;
193     }
194     if(truncated==0 || v<max)
195         put_cabac(c, state, 0);
196 #else
197     if(v <= max_index){
198         for(i=0; i<v; i++){
199             put_cabac(c, state+i, 1);
200         }
201         if(truncated==0 || v<max)
202             put_cabac(c, state+i, 0);
203     }else{
204         for(i=0; i<=max_index; i++){
205             put_cabac(c, state+i, 1);
206         }
207         for(; i<v; i++){
208             put_cabac(c, state+max_index, 1);
209         }
210         if(truncated==0 || v<max)
211             put_cabac(c, state+max_index, 0);
212     }
213 #endif
214 }
215
216 /**
217  * put unary exp golomb k-th order binarization.
218  */
219 static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
220     int i;
221
222     if(v==0)
223         put_cabac(c, state, 0);
224     else{
225         const int sign= v < 0;
226
227         if(is_signed) v= FFABS(v);
228
229         if(v<max){
230             for(i=0; i<v; i++){
231                 put_cabac(c, state, 1);
232                 if(i < max_index) state++;
233             }
234
235             put_cabac(c, state, 0);
236         }else{
237             int m= 1<<k;
238
239             for(i=0; i<max; i++){
240                 put_cabac(c, state, 1);
241                 if(i < max_index) state++;
242             }
243
244             v -= max;
245             while(v >= m){ //FIXME optimize
246                 put_cabac_bypass(c, 1);
247                 v-= m;
248                 m+= m;
249             }
250             put_cabac_bypass(c, 0);
251             while(m>>=1){
252                 put_cabac_bypass(c, v&m);
253             }
254         }
255
256         if(is_signed)
257             put_cabac_bypass(c, sign);
258     }
259 }
260 #endif /* TEST */
261
262 static void refill(CABACContext *c){
263 #if CABAC_BITS == 16
264         c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
265 #else
266         c->low+= c->bytestream[0]<<1;
267 #endif
268     c->low -= CABAC_MASK;
269     c->bytestream+= CABAC_BITS/8;
270 }
271
272 #if ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) )
273 static void refill2(CABACContext *c){
274     int i, x;
275
276     x= c->low ^ (c->low-1);
277     i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
278
279     x= -CABAC_MASK;
280
281 #if CABAC_BITS == 16
282         x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
283 #else
284         x+= c->bytestream[0]<<1;
285 #endif
286
287     c->low += x<<i;
288     c->bytestream+= CABAC_BITS/8;
289 }
290 #endif
291
292 static inline void renorm_cabac_decoder(CABACContext *c){
293     while(c->range < 0x100){
294         c->range+= c->range;
295         c->low+= c->low;
296         if(!(c->low & CABAC_MASK))
297             refill(c);
298     }
299 }
300
301 static inline void renorm_cabac_decoder_once(CABACContext *c){
302     int shift= (uint32_t)(c->range - 0x100)>>31;
303     c->range<<= shift;
304     c->low  <<= shift;
305     if(!(c->low & CABAC_MASK))
306         refill(c);
307 }
308
309 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
310     //FIXME gcc generates duplicate load/stores for c->low and c->range
311 #define LOW          "0"
312 #define RANGE        "4"
313 #if ARCH_X86_64
314 #define BYTESTART   "16"
315 #define BYTE        "24"
316 #define BYTEEND     "32"
317 #else
318 #define BYTESTART   "12"
319 #define BYTE        "16"
320 #define BYTEEND     "20"
321 #endif
322 #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
323     int bit;
324
325 #ifndef BRANCHLESS_CABAC_DECODER
326     __asm__ volatile(
327         "movzbl (%1), %0                        \n\t"
328         "movl "RANGE    "(%2), %%ebx            \n\t"
329         "movl "RANGE    "(%2), %%edx            \n\t"
330         "andl $0xC0, %%ebx                      \n\t"
331         "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t"
332         "movl "LOW      "(%2), %%ebx            \n\t"
333 //eax:state ebx:low, edx:range, esi:RangeLPS
334         "subl %%esi, %%edx                      \n\t"
335         "movl %%edx, %%ecx                      \n\t"
336         "shll $17, %%ecx                        \n\t"
337         "cmpl %%ecx, %%ebx                      \n\t"
338         " ja 1f                                 \n\t"
339
340 #if 1
341         //athlon:4067 P3:4110
342         "lea -0x100(%%edx), %%ecx               \n\t"
343         "shr $31, %%ecx                         \n\t"
344         "shl %%cl, %%edx                        \n\t"
345         "shl %%cl, %%ebx                        \n\t"
346 #else
347         //athlon:4057 P3:4130
348         "cmp $0x100, %%edx                      \n\t" //FIXME avoidable
349         "setb %%cl                              \n\t"
350         "shl %%cl, %%edx                        \n\t"
351         "shl %%cl, %%ebx                        \n\t"
352 #endif
353         "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx   \n\t"
354         "movb %%cl, (%1)                        \n\t"
355 //eax:state ebx:low, edx:range, esi:RangeLPS
356         "test %%bx, %%bx                        \n\t"
357         " jnz 2f                                \n\t"
358         "mov  "BYTE     "(%2), %%"REG_S"        \n\t"
359         "subl $0xFFFF, %%ebx                    \n\t"
360         "movzwl (%%"REG_S"), %%ecx              \n\t"
361         "bswap %%ecx                            \n\t"
362         "shrl $15, %%ecx                        \n\t"
363         "add  $2, %%"REG_S"                     \n\t"
364         "addl %%ecx, %%ebx                      \n\t"
365         "mov  %%"REG_S", "BYTE    "(%2)         \n\t"
366         "jmp 2f                                 \n\t"
367         "1:                                     \n\t"
368 //eax:state ebx:low, edx:range, esi:RangeLPS
369         "subl %%ecx, %%ebx                      \n\t"
370         "movl %%esi, %%edx                      \n\t"
371         "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx   \n\t"
372         "shll %%cl, %%ebx                       \n\t"
373         "shll %%cl, %%edx                       \n\t"
374         "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx   \n\t"
375         "movb %%cl, (%1)                        \n\t"
376         "add  $1, %0                            \n\t"
377         "test %%bx, %%bx                        \n\t"
378         " jnz 2f                                \n\t"
379
380         "mov  "BYTE     "(%2), %%"REG_c"        \n\t"
381         "movzwl (%%"REG_c"), %%esi              \n\t"
382         "bswap %%esi                            \n\t"
383         "shrl $15, %%esi                        \n\t"
384         "subl $0xFFFF, %%esi                    \n\t"
385         "add  $2, %%"REG_c"                     \n\t"
386         "mov  %%"REG_c", "BYTE    "(%2)         \n\t"
387
388         "leal -1(%%ebx), %%ecx                  \n\t"
389         "xorl %%ebx, %%ecx                      \n\t"
390         "shrl $15, %%ecx                        \n\t"
391         "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx   \n\t"
392         "neg %%ecx                              \n\t"
393         "add $7, %%ecx                          \n\t"
394
395         "shll %%cl , %%esi                      \n\t"
396         "addl %%esi, %%ebx                      \n\t"
397         "2:                                     \n\t"
398         "movl %%edx, "RANGE    "(%2)            \n\t"
399         "movl %%ebx, "LOW      "(%2)            \n\t"
400         :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or miscompiles it (for example if "+a"(bit) or "+m"(*state) is used
401         :"r"(state), "r"(c)
402         : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory"
403     );
404     bit&=1;
405 #else /* BRANCHLESS_CABAC_DECODER */
406
407
408 #if HAVE_FAST_CMOV
409 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
410         "mov    "tmp"       , %%ecx                                     \n\t"\
411         "shl    $17         , "tmp"                                     \n\t"\
412         "cmp    "low"       , "tmp"                                     \n\t"\
413         "cmova  %%ecx       , "range"                                   \n\t"\
414         "sbb    %%ecx       , %%ecx                                     \n\t"\
415         "and    %%ecx       , "tmp"                                     \n\t"\
416         "sub    "tmp"       , "low"                                     \n\t"\
417         "xor    %%ecx       , "ret"                                     \n\t"
418 #else /* HAVE_FAST_CMOV */
419 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
420         "mov    "tmp"       , %%ecx                                     \n\t"\
421         "shl    $17         , "tmp"                                     \n\t"\
422         "sub    "low"       , "tmp"                                     \n\t"\
423         "sar    $31         , "tmp"                                     \n\t" /*lps_mask*/\
424         "sub    %%ecx       , "range"                                   \n\t" /*RangeLPS - range*/\
425         "and    "tmp"       , "range"                                   \n\t" /*(RangeLPS - range)&lps_mask*/\
426         "add    %%ecx       , "range"                                   \n\t" /*new range*/\
427         "shl    $17         , %%ecx                                     \n\t"\
428         "and    "tmp"       , %%ecx                                     \n\t"\
429         "sub    %%ecx       , "low"                                     \n\t"\
430         "xor    "tmp"       , "ret"                                     \n\t"
431 #endif /* HAVE_FAST_CMOV */
432
433
434 #define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
435         "movzbl "statep"    , "ret"                                     \n\t"\
436         "mov    "range"     , "tmp"                                     \n\t"\
437         "and    $0xC0       , "range"                                   \n\t"\
438         "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
439         "sub    "range"     , "tmp"                                     \n\t"\
440         BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
441         "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx          \n\t"\
442         "shl    %%cl        , "range"                                   \n\t"\
443         "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp"          \n\t"\
444         "mov    "tmpbyte"   , "statep"                                  \n\t"\
445         "shl    %%cl        , "low"                                     \n\t"\
446         "test   "lowword"   , "lowword"                                 \n\t"\
447         " jnz   1f                                                      \n\t"\
448         "mov "BYTE"("cabac"), %%"REG_c"                                 \n\t"\
449         "movzwl (%%"REG_c")     , "tmp"                                 \n\t"\
450         "bswap  "tmp"                                                   \n\t"\
451         "shr    $15         , "tmp"                                     \n\t"\
452         "sub    $0xFFFF     , "tmp"                                     \n\t"\
453         "add    $2          , %%"REG_c"                                 \n\t"\
454         "mov    %%"REG_c"   , "BYTE    "("cabac")                       \n\t"\
455         "lea    -1("low")   , %%ecx                                     \n\t"\
456         "xor    "low"       , %%ecx                                     \n\t"\
457         "shr    $15         , %%ecx                                     \n\t"\
458         "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx            \n\t"\
459         "neg    %%ecx                                                   \n\t"\
460         "add    $7          , %%ecx                                     \n\t"\
461         "shl    %%cl        , "tmp"                                     \n\t"\
462         "add    "tmp"       , "low"                                     \n\t"\
463         "1:                                                             \n\t"
464
465     __asm__ volatile(
466         "movl "RANGE    "(%2), %%esi            \n\t"
467         "movl "LOW      "(%2), %%ebx            \n\t"
468         BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl")
469         "movl %%esi, "RANGE    "(%2)            \n\t"
470         "movl %%ebx, "LOW      "(%2)            \n\t"
471
472         :"=&a"(bit)
473         :"r"(state), "r"(c)
474         : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
475     );
476     bit&=1;
477 #endif /* BRANCHLESS_CABAC_DECODER */
478 #else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */
479     int s = *state;
480     int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
481     int bit, lps_mask av_unused;
482
483     c->range -= RangeLPS;
484 #ifndef BRANCHLESS_CABAC_DECODER
485     if(c->low < (c->range<<(CABAC_BITS+1))){
486         bit= s&1;
487         *state= ff_h264_mps_state[s];
488         renorm_cabac_decoder_once(c);
489     }else{
490         bit= ff_h264_norm_shift[RangeLPS];
491         c->low -= (c->range<<(CABAC_BITS+1));
492         *state= ff_h264_lps_state[s];
493         c->range = RangeLPS<<bit;
494         c->low <<= bit;
495         bit= (s&1)^1;
496
497         if(!(c->low & CABAC_MASK)){
498             refill2(c);
499         }
500     }
501 #else /* BRANCHLESS_CABAC_DECODER */
502     lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31;
503
504     c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask;
505     c->range += (RangeLPS - c->range) & lps_mask;
506
507     s^=lps_mask;
508     *state= (ff_h264_mlps_state+128)[s];
509     bit= s&1;
510
511     lps_mask= ff_h264_norm_shift[c->range];
512     c->range<<= lps_mask;
513     c->low  <<= lps_mask;
514     if(!(c->low & CABAC_MASK))
515         refill2(c);
516 #endif /* BRANCHLESS_CABAC_DECODER */
517 #endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */
518     return bit;
519 }
520
521 static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){
522     return get_cabac_inline(c,state);
523 }
524
525 static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
526     return get_cabac_inline(c,state);
527 }
528
529 static int av_unused get_cabac_bypass(CABACContext *c){
530 #if 0 //not faster
531     int bit;
532     __asm__ volatile(
533         "movl "RANGE    "(%1), %%ebx            \n\t"
534         "movl "LOW      "(%1), %%eax            \n\t"
535         "shl $17, %%ebx                         \n\t"
536         "add %%eax, %%eax                       \n\t"
537         "sub %%ebx, %%eax                       \n\t"
538         "cltd                                   \n\t"
539         "and %%edx, %%ebx                       \n\t"
540         "add %%ebx, %%eax                       \n\t"
541         "test %%ax, %%ax                        \n\t"
542         " jnz 1f                                \n\t"
543         "movl "BYTE     "(%1), %%"REG_b"        \n\t"
544         "subl $0xFFFF, %%eax                    \n\t"
545         "movzwl (%%"REG_b"), %%ecx              \n\t"
546         "bswap %%ecx                            \n\t"
547         "shrl $15, %%ecx                        \n\t"
548         "addl $2, %%"REG_b"                     \n\t"
549         "addl %%ecx, %%eax                      \n\t"
550         "movl %%"REG_b", "BYTE     "(%1)        \n\t"
551         "1:                                     \n\t"
552         "movl %%eax, "LOW      "(%1)            \n\t"
553
554         :"=&d"(bit)
555         :"r"(c)
556         : "%eax", "%"REG_b, "%ecx", "memory"
557     );
558     return bit+1;
559 #else
560     int range;
561     c->low += c->low;
562
563     if(!(c->low & CABAC_MASK))
564         refill(c);
565
566     range= c->range<<(CABAC_BITS+1);
567     if(c->low < range){
568         return 0;
569     }else{
570         c->low -= range;
571         return 1;
572     }
573 #endif
574 }
575
576
577 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
578 #if ARCH_X86 && HAVE_EBX_AVAILABLE
579     __asm__ volatile(
580         "movl "RANGE    "(%1), %%ebx            \n\t"
581         "movl "LOW      "(%1), %%eax            \n\t"
582         "shl $17, %%ebx                         \n\t"
583         "add %%eax, %%eax                       \n\t"
584         "sub %%ebx, %%eax                       \n\t"
585         "cltd                                   \n\t"
586         "and %%edx, %%ebx                       \n\t"
587         "add %%ebx, %%eax                       \n\t"
588         "xor %%edx, %%ecx                       \n\t"
589         "sub %%edx, %%ecx                       \n\t"
590         "test %%ax, %%ax                        \n\t"
591         " jnz 1f                                \n\t"
592         "mov  "BYTE     "(%1), %%"REG_b"        \n\t"
593         "subl $0xFFFF, %%eax                    \n\t"
594         "movzwl (%%"REG_b"), %%edx              \n\t"
595         "bswap %%edx                            \n\t"
596         "shrl $15, %%edx                        \n\t"
597         "add  $2, %%"REG_b"                     \n\t"
598         "addl %%edx, %%eax                      \n\t"
599         "mov  %%"REG_b", "BYTE     "(%1)        \n\t"
600         "1:                                     \n\t"
601         "movl %%eax, "LOW      "(%1)            \n\t"
602
603         :"+c"(val)
604         :"r"(c)
605         : "%eax", "%"REG_b, "%edx", "memory"
606     );
607     return val;
608 #else
609     int range, mask;
610     c->low += c->low;
611
612     if(!(c->low & CABAC_MASK))
613         refill(c);
614
615     range= c->range<<(CABAC_BITS+1);
616     c->low -= range;
617     mask= c->low >> 31;
618     range &= mask;
619     c->low += range;
620     return (val^mask)-mask;
621 #endif
622 }
623
624 /**
625  *
626  * @return the number of bytes read or 0 if no end
627  */
628 static int av_unused get_cabac_terminate(CABACContext *c){
629     c->range -= 2;
630     if(c->low < c->range<<(CABAC_BITS+1)){
631         renorm_cabac_decoder_once(c);
632         return 0;
633     }else{
634         return c->bytestream - c->bytestream_start;
635     }
636 }
637
638 #if 0
639 /**
640  * Get (truncated) unary binarization.
641  */
642 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
643     int i;
644
645     for(i=0; i<max; i++){
646         if(get_cabac(c, state)==0)
647             return i;
648
649         if(i< max_index) state++;
650     }
651
652     return truncated ? max : -1;
653 }
654
655 /**
656  * get unary exp golomb k-th order binarization.
657  */
658 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
659     int i, v;
660     int m= 1<<k;
661
662     if(get_cabac(c, state)==0)
663         return 0;
664
665     if(0 < max_index) state++;
666
667     for(i=1; i<max; i++){
668         if(get_cabac(c, state)==0){
669             if(is_signed && get_cabac_bypass(c)){
670                 return -i;
671             }else
672                 return i;
673         }
674
675         if(i < max_index) state++;
676     }
677
678     while(get_cabac_bypass(c)){
679         i+= m;
680         m+= m;
681     }
682
683     v=0;
684     while(m>>=1){
685         v+= v + get_cabac_bypass(c);
686     }
687     i += v;
688
689     if(is_signed && get_cabac_bypass(c)){
690         return -i;
691     }else
692         return i;
693 }
694 #endif /* 0 */
695
696 #endif /* AVCODEC_CABAC_H */