00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef AVCODEC_ARM_VP56_ARITH_H
00022 #define AVCODEC_ARM_VP56_ARITH_H
00023
00024 #if HAVE_ARMV6 && HAVE_INLINE_ASM
00025
00026 #define vp56_rac_get_prob vp56_rac_get_prob_armv6
00027 static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr)
00028 {
00029 unsigned shift = ff_vp56_norm_shift[c->high];
00030 unsigned code_word = c->code_word << shift;
00031 unsigned high = c->high << shift;
00032 unsigned bit;
00033
00034 __asm__ ("adds %3, %3, %0 \n"
00035 "cmpcs %7, %4 \n"
00036 "ldrcsh %2, [%4], #2 \n"
00037 "rsb %0, %6, #256 \n"
00038 "smlabb %0, %5, %6, %0 \n"
00039 "rev16cs %2, %2 \n"
00040 "orrcs %1, %1, %2, lsl %3 \n"
00041 "subcs %3, %3, #16 \n"
00042 "lsr %0, %0, #8 \n"
00043 "cmp %1, %0, lsl #16 \n"
00044 "subge %1, %1, %0, lsl #16 \n"
00045 "subge %0, %5, %0 \n"
00046 "movge %2, #1 \n"
00047 "movlt %2, #0 \n"
00048 : "=&r"(c->high), "=&r"(c->code_word), "=&r"(bit),
00049 "+&r"(c->bits), "+&r"(c->buffer)
00050 : "r"(high), "r"(pr), "r"(c->end - 1),
00051 "0"(shift), "1"(code_word)
00052 : "cc");
00053
00054 return bit;
00055 }
00056
00057 #define vp56_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6
00058 static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr)
00059 {
00060 unsigned shift = ff_vp56_norm_shift[c->high];
00061 unsigned code_word = c->code_word << shift;
00062 unsigned high = c->high << shift;
00063 unsigned low;
00064 unsigned tmp;
00065
00066 __asm__ ("adds %3, %3, %0 \n"
00067 "cmpcs %7, %4 \n"
00068 "ldrcsh %2, [%4], #2 \n"
00069 "rsb %0, %6, #256 \n"
00070 "smlabb %0, %5, %6, %0 \n"
00071 "rev16cs %2, %2 \n"
00072 "orrcs %1, %1, %2, lsl %3 \n"
00073 "subcs %3, %3, #16 \n"
00074 "lsr %0, %0, #8 \n"
00075 "lsl %2, %0, #16 \n"
00076 : "=&r"(low), "+&r"(code_word), "=&r"(tmp),
00077 "+&r"(c->bits), "+&r"(c->buffer)
00078 : "r"(high), "r"(pr), "r"(c->end - 1), "0"(shift)
00079 : "cc");
00080
00081 if (code_word >= tmp) {
00082 c->high = high - low;
00083 c->code_word = code_word - tmp;
00084 return 1;
00085 }
00086
00087 c->high = low;
00088 c->code_word = code_word;
00089 return 0;
00090 }
00091
00092 #endif
00093
00094 #endif