1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#ifndef AVCODEC_AARCH64_CABAC_H 20cabdff1aSopenharmony_ci#define AVCODEC_AARCH64_CABAC_H 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "config.h" 23cabdff1aSopenharmony_ci#if HAVE_INLINE_ASM 24cabdff1aSopenharmony_ci 25cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 26cabdff1aSopenharmony_ci#include "libavutil/internal.h" 27cabdff1aSopenharmony_ci#include "libavcodec/cabac.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#define get_cabac_inline get_cabac_inline_aarch64 30cabdff1aSopenharmony_cistatic av_always_inline int get_cabac_inline_aarch64(CABACContext *c, 31cabdff1aSopenharmony_ci uint8_t *const state) 32cabdff1aSopenharmony_ci{ 33cabdff1aSopenharmony_ci int bit; 34cabdff1aSopenharmony_ci void *reg_a, *reg_b, *reg_c, *tmp; 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci __asm__ volatile( 37cabdff1aSopenharmony_ci "ldrb %w[bit] , [%[state]] \n\t" 38cabdff1aSopenharmony_ci "add %[r_b] , %[tables] , %[lps_off] \n\t" 39cabdff1aSopenharmony_ci "mov %w[tmp] , %w[range] \n\t" 40cabdff1aSopenharmony_ci "and %w[range] , %w[range] , #0xC0 \n\t" 41cabdff1aSopenharmony_ci "lsl %w[r_c] , %w[range] , #1 \n\t" 42cabdff1aSopenharmony_ci "add %[r_b] , %[r_b] , %w[bit], UXTW \n\t" 43cabdff1aSopenharmony_ci "ldrb %w[range] , [%[r_b], %w[r_c], SXTW] \n\t" 44cabdff1aSopenharmony_ci "sub %w[r_c] , %w[tmp] , %w[range] \n\t" 45cabdff1aSopenharmony_ci "lsl %w[tmp] , %w[r_c] , #17 \n\t" 46cabdff1aSopenharmony_ci "cmp %w[tmp] , %w[low] \n\t" 47cabdff1aSopenharmony_ci "csel %w[tmp] , %w[tmp] , wzr , cc \n\t" 48cabdff1aSopenharmony_ci "csel %w[range] , %w[r_c] , %w[range], gt \n\t" 49cabdff1aSopenharmony_ci "cinv %w[bit] , %w[bit] , cc \n\t" 50cabdff1aSopenharmony_ci "sub %w[low] , %w[low] , %w[tmp] \n\t" 51cabdff1aSopenharmony_ci "add %[r_b] , %[tables] , %[norm_off] \n\t" 52cabdff1aSopenharmony_ci "add %[r_a] , %[tables] , %[mlps_off] \n\t" 53cabdff1aSopenharmony_ci "ldrb %w[tmp] , [%[r_b], %w[range], SXTW] \n\t" 54cabdff1aSopenharmony_ci "ldrb %w[r_a] , [%[r_a], %w[bit], SXTW] \n\t" 55cabdff1aSopenharmony_ci "lsl %w[low] , %w[low] , %w[tmp] \n\t" 56cabdff1aSopenharmony_ci "lsl %w[range] , %w[range] , %w[tmp] \n\t" 57cabdff1aSopenharmony_ci "uxth %w[r_c] , %w[low] \n\t" 58cabdff1aSopenharmony_ci "strb %w[r_a] , [%[state]] \n\t" 59cabdff1aSopenharmony_ci "cbnz %w[r_c] , 2f \n\t" 60cabdff1aSopenharmony_ci "ldr %[r_c] , [%[c], %[byte]] \n\t" 61cabdff1aSopenharmony_ci "ldr %[r_a] , [%[c], %[end]] \n\t" 62cabdff1aSopenharmony_ci "ldrh %w[tmp] , [%[r_c]] \n\t" 63cabdff1aSopenharmony_ci "cmp %[r_c] , %[r_a] \n\t" 64cabdff1aSopenharmony_ci "b.ge 1f \n\t" 65cabdff1aSopenharmony_ci "add %[r_a] , %[r_c] , #2 \n\t" 66cabdff1aSopenharmony_ci "str %[r_a] , [%[c], %[byte]] \n\t" 67cabdff1aSopenharmony_ci "1: \n\t" 68cabdff1aSopenharmony_ci "sub %w[r_c] , %w[low] , #1 \n\t" 69cabdff1aSopenharmony_ci "eor %w[r_c] , %w[r_c] , %w[low] \n\t" 70cabdff1aSopenharmony_ci "rev %w[tmp] , %w[tmp] \n\t" 71cabdff1aSopenharmony_ci "lsr %w[r_c] , %w[r_c] , #15 \n\t" 72cabdff1aSopenharmony_ci "lsr %w[tmp] , %w[tmp] , #15 \n\t" 73cabdff1aSopenharmony_ci "ldrb %w[r_c] , [%[r_b], %w[r_c], SXTW] \n\t" 74cabdff1aSopenharmony_ci "mov %w[r_b] , #0xFFFF \n\t" 75cabdff1aSopenharmony_ci "mov %w[r_a] , #7 \n\t" 76cabdff1aSopenharmony_ci "sub %w[tmp] , %w[tmp] , %w[r_b] \n\t" 77cabdff1aSopenharmony_ci "sub %w[r_c] , %w[r_a] , %w[r_c] \n\t" 78cabdff1aSopenharmony_ci "lsl %w[tmp] , %w[tmp] , %w[r_c] \n\t" 79cabdff1aSopenharmony_ci "add %w[low] , %w[low] , %w[tmp] \n\t" 80cabdff1aSopenharmony_ci "2: \n\t" 81cabdff1aSopenharmony_ci : [bit]"=&r"(bit), 82cabdff1aSopenharmony_ci [low]"+&r"(c->low), 83cabdff1aSopenharmony_ci [range]"+&r"(c->range), 84cabdff1aSopenharmony_ci [r_a]"=&r"(reg_a), 85cabdff1aSopenharmony_ci [r_b]"=&r"(reg_b), 86cabdff1aSopenharmony_ci [r_c]"=&r"(reg_c), 87cabdff1aSopenharmony_ci [tmp]"=&r"(tmp) 88cabdff1aSopenharmony_ci : [c]"r"(c), 89cabdff1aSopenharmony_ci [state]"r"(state), 90cabdff1aSopenharmony_ci [tables]"r"(ff_h264_cabac_tables), 91cabdff1aSopenharmony_ci [byte]"i"(offsetof(CABACContext, bytestream)), 92cabdff1aSopenharmony_ci [end]"i"(offsetof(CABACContext, bytestream_end)), 93cabdff1aSopenharmony_ci [norm_off]"I"(H264_NORM_SHIFT_OFFSET), 94cabdff1aSopenharmony_ci [lps_off]"I"(H264_LPS_RANGE_OFFSET), 95cabdff1aSopenharmony_ci [mlps_off]"I"(H264_MLPS_STATE_OFFSET + 128) 96cabdff1aSopenharmony_ci : "memory", "cc" 97cabdff1aSopenharmony_ci ); 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci return bit & 1; 100cabdff1aSopenharmony_ci} 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci#endif /* HAVE_INLINE_ASM */ 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci#endif /* AVCODEC_AARCH64_CABAC_H */ 105