Libav 0.7.1
|
00001 /* 00002 * Copyright (C) 2010 Mans Rullgard <mans@mansr.com> 00003 * 00004 * This file is part of Libav. 00005 * 00006 * Libav is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * Libav is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with Libav; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 /* AVCODEC_ARM_VP56_ARITH_H */