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__ volatile ("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
00053 return bit;
00054 }
00055
00056 #define vp56_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6
00057 static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr)
00058 {
00059 unsigned shift = ff_vp56_norm_shift[c->high];
00060 unsigned code_word = c->code_word << shift;
00061 unsigned high = c->high << shift;
00062 unsigned low;
00063 unsigned tmp;
00064
00065 __asm__ volatile ("adds %3, %3, %0 \n"
00066 "cmpcs %7, %4 \n"
00067 "ldrcsh %2, [%4], #2 \n"
00068 "rsb %0, %6, #256 \n"
00069 "smlabb %0, %5, %6, %0 \n"
00070 "rev16cs %2, %2 \n"
00071 "orrcs %1, %1, %2, lsl %3 \n"
00072 "subcs %3, %3, #16 \n"
00073 "lsr %0, %0, #8 \n"
00074 "lsl %2, %0, #16 \n"
00075 : "=&r"(low), "+&r"(code_word), "=&r"(tmp),
00076 "+&r"(c->bits), "+&r"(c->buffer)
00077 : "r"(high), "r"(pr), "r"(c->end - 1), "0"(shift));
00078
00079 if (code_word >= tmp) {
00080 c->high = high - low;
00081 c->code_word = code_word - tmp;
00082 return 1;
00083 }
00084
00085 c->high = low;
00086 c->code_word = code_word;
00087 return 0;
00088 }
00089
00090 #endif
00091
00092 #endif