+#define LOW "0"
+#define RANGE "4"
+#ifdef ARCH_X86_64
+#define BYTESTART "16"
+#define BYTE "24"
+#define BYTEEND "32"
+#else
+#define BYTESTART "12"
+#define BYTE "16"
+#define BYTEEND "20"
+#endif
+#if defined(ARCH_X86) && defined(CONFIG_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS)
+ int bit;
+
+#ifndef BRANCHLESS_CABAC_DECODER
+ asm volatile(
+ "movzbl (%1), %0 \n\t"
+ "movl "RANGE "(%2), %%ebx \n\t"
+ "movl "RANGE "(%2), %%edx \n\t"
+ "andl $0xC0, %%ebx \n\t"
+ "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t"
+ "movl "LOW "(%2), %%ebx \n\t"
+//eax:state ebx:low, edx:range, esi:RangeLPS
+ "subl %%esi, %%edx \n\t"
+ "movl %%edx, %%ecx \n\t"
+ "shll $17, %%ecx \n\t"
+ "cmpl %%ecx, %%ebx \n\t"
+ " ja 1f \n\t"
+
+#if 1
+ //athlon:4067 P3:4110
+ "lea -0x100(%%edx), %%ecx \n\t"
+ "shr $31, %%ecx \n\t"
+ "shl %%cl, %%edx \n\t"
+ "shl %%cl, %%ebx \n\t"
+#else
+ //athlon:4057 P3:4130
+ "cmp $0x100, %%edx \n\t" //FIXME avoidable
+ "setb %%cl \n\t"
+ "shl %%cl, %%edx \n\t"
+ "shl %%cl, %%ebx \n\t"
+#endif
+ "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t"
+ "movb %%cl, (%1) \n\t"
+//eax:state ebx:low, edx:range, esi:RangeLPS
+ "test %%bx, %%bx \n\t"
+ " jnz 2f \n\t"
+ "mov "BYTE "(%2), %%"REG_S" \n\t"
+ "subl $0xFFFF, %%ebx \n\t"
+ "movzwl (%%"REG_S"), %%ecx \n\t"
+ "bswap %%ecx \n\t"
+ "shrl $15, %%ecx \n\t"
+ "add $2, %%"REG_S" \n\t"
+ "addl %%ecx, %%ebx \n\t"
+ "mov %%"REG_S", "BYTE "(%2) \n\t"
+ "jmp 2f \n\t"
+ "1: \n\t"
+//eax:state ebx:low, edx:range, esi:RangeLPS
+ "subl %%ecx, %%ebx \n\t"
+ "movl %%esi, %%edx \n\t"
+ "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t"
+ "shll %%cl, %%ebx \n\t"
+ "shll %%cl, %%edx \n\t"
+ "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t"
+ "movb %%cl, (%1) \n\t"
+ "add $1, %0 \n\t"
+ "test %%bx, %%bx \n\t"
+ " jnz 2f \n\t"
+
+ "mov "BYTE "(%2), %%"REG_c" \n\t"
+ "movzwl (%%"REG_c"), %%esi \n\t"
+ "bswap %%esi \n\t"
+ "shrl $15, %%esi \n\t"
+ "subl $0xFFFF, %%esi \n\t"
+ "add $2, %%"REG_c" \n\t"
+ "mov %%"REG_c", "BYTE "(%2) \n\t"
+
+ "leal -1(%%ebx), %%ecx \n\t"
+ "xorl %%ebx, %%ecx \n\t"
+ "shrl $15, %%ecx \n\t"
+ "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"
+ "neg %%ecx \n\t"
+ "add $7, %%ecx \n\t"
+
+ "shll %%cl , %%esi \n\t"
+ "addl %%esi, %%ebx \n\t"
+ "2: \n\t"
+ "movl %%edx, "RANGE "(%2) \n\t"
+ "movl %%ebx, "LOW "(%2) \n\t"
+ :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or misscompiles it (for example if "+a"(bit) or "+m"(*state) is used
+ :"r"(state), "r"(c)
+ : "%"REG_c, "%ebx", "%edx", "%"REG_S, "memory"
+ );
+ bit&=1;
+#else /* BRANCHLESS_CABAC_DECODER */
+
+
+#if defined HAVE_FAST_CMOV
+#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
+ "mov "tmp" , %%ecx \n\t"\
+ "shl $17 , "tmp" \n\t"\
+ "cmp "low" , "tmp" \n\t"\
+ "cmova %%ecx , "range" \n\t"\
+ "sbb %%ecx , %%ecx \n\t"\
+ "and %%ecx , "tmp" \n\t"\
+ "sub "tmp" , "low" \n\t"\
+ "xor %%ecx , "ret" \n\t"
+#else /* HAVE_FAST_CMOV */
+#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
+ "mov "tmp" , %%ecx \n\t"\
+ "shl $17 , "tmp" \n\t"\
+ "sub "low" , "tmp" \n\t"\
+ "sar $31 , "tmp" \n\t" /*lps_mask*/\
+ "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\
+ "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\
+ "add %%ecx , "range" \n\t" /*new range*/\
+ "shl $17 , %%ecx \n\t"\
+ "and "tmp" , %%ecx \n\t"\
+ "sub %%ecx , "low" \n\t"\
+ "xor "tmp" , "ret" \n\t"
+#endif /* HAVE_FAST_CMOV */
+
+
+#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
+ "movzbl "statep" , "ret" \n\t"\
+ "mov "range" , "tmp" \n\t"\
+ "and $0xC0 , "range" \n\t"\
+ "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
+ "sub "range" , "tmp" \n\t"\
+ BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
+ "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\
+ "shl %%cl , "range" \n\t"\
+ "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\
+ "mov "tmpbyte" , "statep" \n\t"\
+ "shl %%cl , "low" \n\t"\
+ "test "lowword" , "lowword" \n\t"\
+ " jnz 1f \n\t"\
+ "mov "BYTE"("cabac"), %%"REG_c" \n\t"\
+ "movzwl (%%"REG_c") , "tmp" \n\t"\
+ "bswap "tmp" \n\t"\
+ "shr $15 , "tmp" \n\t"\
+ "sub $0xFFFF , "tmp" \n\t"\
+ "add $2 , %%"REG_c" \n\t"\
+ "mov %%"REG_c" , "BYTE "("cabac") \n\t"\
+ "lea -1("low") , %%ecx \n\t"\
+ "xor "low" , %%ecx \n\t"\
+ "shr $15 , %%ecx \n\t"\
+ "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\
+ "neg %%ecx \n\t"\
+ "add $7 , %%ecx \n\t"\
+ "shl %%cl , "tmp" \n\t"\
+ "add "tmp" , "low" \n\t"\
+ "1: \n\t"
+
+ asm volatile(
+ "movl "RANGE "(%2), %%esi \n\t"
+ "movl "LOW "(%2), %%ebx \n\t"
+ BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl")
+ "movl %%esi, "RANGE "(%2) \n\t"
+ "movl %%ebx, "LOW "(%2) \n\t"
+
+ :"=&a"(bit)
+ :"r"(state), "r"(c)
+ : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
+ );
+ bit&=1;
+#endif /* BRANCHLESS_CABAC_DECODER */
+#else /* defined(ARCH_X86) && defined(CONFIG_7REGS) && defined(HAVE_EBX_AVAILABLE) && !defined(BROKEN_RELOCATIONS) */