yading@10: /* yading@10: * Copyright (C) 2010 Mans Rullgard yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: #ifndef AVCODEC_ARM_VP56_ARITH_H yading@10: #define AVCODEC_ARM_VP56_ARITH_H yading@10: yading@10: #if CONFIG_THUMB yading@10: # define A(x) yading@10: # define T(x) x yading@10: #else yading@10: # define A(x) x yading@10: # define T(x) yading@10: #endif yading@10: yading@10: #if CONFIG_THUMB || defined __clang__ yading@10: # define L(x) yading@10: # define U(x) x yading@10: #else yading@10: # define L(x) x yading@10: # define U(x) yading@10: #endif yading@10: yading@10: #if HAVE_ARMV6_INLINE yading@10: yading@10: #define vp56_rac_get_prob vp56_rac_get_prob_armv6 yading@10: static inline int vp56_rac_get_prob_armv6(VP56RangeCoder *c, int pr) yading@10: { yading@10: unsigned shift = ff_vp56_norm_shift[c->high]; yading@10: unsigned code_word = c->code_word << shift; yading@10: unsigned high = c->high << shift; yading@10: unsigned bit; yading@10: yading@10: __asm__ ("adds %3, %3, %0 \n" yading@10: "itt cs \n" yading@10: "cmpcs %7, %4 \n" yading@10: L("ldrcsh %2, [%4], #2 \n") yading@10: U("ldrhcs %2, [%4], #2 \n") yading@10: "rsb %0, %6, #256 \n" yading@10: "smlabb %0, %5, %6, %0 \n" yading@10: T("itttt cs \n") yading@10: "rev16cs %2, %2 \n" yading@10: T("lslcs %2, %2, %3 \n") yading@10: T("orrcs %1, %1, %2 \n") yading@10: A("orrcs %1, %1, %2, lsl %3 \n") yading@10: "subcs %3, %3, #16 \n" yading@10: "lsr %0, %0, #8 \n" yading@10: "cmp %1, %0, lsl #16 \n" yading@10: "ittte ge \n" yading@10: "subge %1, %1, %0, lsl #16 \n" yading@10: "subge %0, %5, %0 \n" yading@10: "movge %2, #1 \n" yading@10: "movlt %2, #0 \n" yading@10: : "=&r"(c->high), "=&r"(c->code_word), "=&r"(bit), yading@10: "+&r"(c->bits), "+&r"(c->buffer) yading@10: : "r"(high), "r"(pr), "r"(c->end - 1), yading@10: "0"(shift), "1"(code_word) yading@10: : "cc"); yading@10: yading@10: return bit; yading@10: } yading@10: yading@10: #define vp56_rac_get_prob_branchy vp56_rac_get_prob_branchy_armv6 yading@10: static inline int vp56_rac_get_prob_branchy_armv6(VP56RangeCoder *c, int pr) yading@10: { yading@10: unsigned shift = ff_vp56_norm_shift[c->high]; yading@10: unsigned code_word = c->code_word << shift; yading@10: unsigned high = c->high << shift; yading@10: unsigned low; yading@10: unsigned tmp; yading@10: yading@10: __asm__ ("adds %3, %3, %0 \n" yading@10: "itt cs \n" yading@10: "cmpcs %7, %4 \n" yading@10: L("ldrcsh %2, [%4], #2 \n") yading@10: U("ldrhcs %2, [%4], #2 \n") yading@10: "rsb %0, %6, #256 \n" yading@10: "smlabb %0, %5, %6, %0 \n" yading@10: T("itttt cs \n") yading@10: "rev16cs %2, %2 \n" yading@10: T("lslcs %2, %2, %3 \n") yading@10: T("orrcs %1, %1, %2 \n") yading@10: A("orrcs %1, %1, %2, lsl %3 \n") yading@10: "subcs %3, %3, #16 \n" yading@10: "lsr %0, %0, #8 \n" yading@10: "lsl %2, %0, #16 \n" yading@10: : "=&r"(low), "+&r"(code_word), "=&r"(tmp), yading@10: "+&r"(c->bits), "+&r"(c->buffer) yading@10: : "r"(high), "r"(pr), "r"(c->end - 1), "0"(shift) yading@10: : "cc"); yading@10: yading@10: if (code_word >= tmp) { yading@10: c->high = high - low; yading@10: c->code_word = code_word - tmp; yading@10: return 1; yading@10: } yading@10: yading@10: c->high = low; yading@10: c->code_word = code_word; yading@10: return 0; yading@10: } yading@10: yading@10: #endif yading@10: yading@10: #endif /* AVCODEC_ARM_VP56_ARITH_H */