FFmpeg
Loading...
Searching...
No Matches
cabac.h
Go to the documentation of this file.
1/*
2 * Loongson optimized cabac
3 *
4 * Copyright (c) 2020 Loongson Technology Corporation Limited
5 * Contributed by Shiyou Yin <yinshiyou-hf@loongson.cn>
6 * Gu Xiwei(guxiwei-hf@loongson.cn)
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#ifndef AVCODEC_LOONGARCH_CABAC_H
26#define AVCODEC_LOONGARCH_CABAC_H
27
29#include "libavcodec/cabac.h"
30#include "config.h"
31
32#define GET_CABAC_LOONGARCH_UNCBSR \
33 "ld.bu %[bit], %[state], 0x0 \n\t" \
34 "andi %[tmp0], %[c_range], 0xC0 \n\t" \
35 "slli.d %[tmp0], %[tmp0], 0x01 \n\t" \
36 "add.d %[tmp0], %[tmp0], %[tables] \n\t" \
37 "add.d %[tmp0], %[tmp0], %[bit] \n\t" \
38 /* tmp1: RangeLPS */ \
39 "ld.bu %[tmp1], %[tmp0], %[lps_off] \n\t" \
40 \
41 "sub.d %[c_range], %[c_range], %[tmp1] \n\t" \
42 "slli.d %[tmp0], %[c_range], 0x11 \n\t" \
43 "bge %[tmp0], %[c_low], 1f \n\t" \
44 "move %[c_range], %[tmp1] \n\t" \
45 "nor %[bit], %[bit], %[bit] \n\t" \
46 "sub.d %[c_low], %[c_low], %[tmp0] \n\t" \
47 \
48 "1: \n\t" \
49 /* tmp1: *state */ \
50 "add.d %[tmp0], %[tables], %[bit] \n\t" \
51 "ld.bu %[tmp1], %[tmp0], %[mlps_off] \n\t" \
52 /* tmp2: lps_mask */ \
53 "add.d %[tmp0], %[tables], %[c_range] \n\t" \
54 "ld.bu %[tmp2], %[tmp0], %[norm_off] \n\t" \
55 \
56 "andi %[bit], %[bit], 0x01 \n\t" \
57 "st.b %[tmp1], %[state], 0x0 \n\t" \
58 "sll.d %[c_range], %[c_range], %[tmp2] \n\t" \
59 "sll.d %[c_low], %[c_low], %[tmp2] \n\t" \
60 \
61 "and %[tmp1], %[c_low], %[cabac_mask] \n\t" \
62 "bnez %[tmp1], 1f \n\t" \
63 "ld.hu %[tmp1], %[c_bytestream], 0x0 \n\t" \
64 "ctz.d %[tmp0], %[c_low] \n\t" \
65 "addi.d %[tmp2], %[tmp0], -16 \n\t" \
66 "revb.2h %[tmp0], %[tmp1] \n\t" \
67 "slli.d %[tmp0], %[tmp0], 0x01 \n\t" \
68 "sub.d %[tmp0], %[tmp0], %[cabac_mask] \n\t" \
69 "sll.d %[tmp0], %[tmp0], %[tmp2] \n\t" \
70 "add.d %[c_low], %[c_low], %[tmp0] \n\t" \
71 "addi.d %[c_bytestream], %[c_bytestream], 0x02 \n\t" \
72 "1: \n\t" \
73
74#define GET_CABAC_LOONGARCH \
75 "ld.bu %[bit], %[state], 0x0 \n\t" \
76 "andi %[tmp0], %[c_range], 0xC0 \n\t" \
77 "slli.d %[tmp0], %[tmp0], 0x01 \n\t" \
78 "add.d %[tmp0], %[tmp0], %[tables] \n\t" \
79 "add.d %[tmp0], %[tmp0], %[bit] \n\t" \
80 /* tmp1: RangeLPS */ \
81 "ld.bu %[tmp1], %[tmp0], %[lps_off] \n\t" \
82 \
83 "sub.d %[c_range], %[c_range], %[tmp1] \n\t" \
84 "slli.d %[tmp0], %[c_range], 0x11 \n\t" \
85 "bge %[tmp0], %[c_low], 1f \n\t" \
86 "move %[c_range], %[tmp1] \n\t" \
87 "nor %[bit], %[bit], %[bit] \n\t" \
88 "sub.d %[c_low], %[c_low], %[tmp0] \n\t" \
89 \
90 "1: \n\t" \
91 /* tmp1: *state */ \
92 "add.d %[tmp0], %[tables], %[bit] \n\t" \
93 "ld.bu %[tmp1], %[tmp0], %[mlps_off] \n\t" \
94 /* tmp2: lps_mask */ \
95 "add.d %[tmp0], %[tables], %[c_range] \n\t" \
96 "ld.bu %[tmp2], %[tmp0], %[norm_off] \n\t" \
97 \
98 "andi %[bit], %[bit], 0x01 \n\t" \
99 "st.b %[tmp1], %[state], 0x0 \n\t" \
100 "sll.d %[c_range], %[c_range], %[tmp2] \n\t" \
101 "sll.d %[c_low], %[c_low], %[tmp2] \n\t" \
102 \
103 "and %[tmp1], %[c_low], %[cabac_mask] \n\t" \
104 "bnez %[tmp1], 1f \n\t" \
105 "ld.hu %[tmp1], %[c_bytestream], 0x0 \n\t" \
106 "ctz.d %[tmp0], %[c_low] \n\t" \
107 "addi.d %[tmp2], %[tmp0], -16 \n\t" \
108 "revb.2h %[tmp0], %[tmp1] \n\t" \
109 "slli.d %[tmp0], %[tmp0], 0x01 \n\t" \
110 "sub.d %[tmp0], %[tmp0], %[cabac_mask] \n\t" \
111 "sll.d %[tmp0], %[tmp0], %[tmp2] \n\t" \
112 \
113 "add.d %[c_low], %[c_low], %[tmp0] \n\t" \
114 \
115 "slt %[tmp0], %[c_bytestream], %[c_bytestream_end] \n\t" \
116 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t" \
117 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t" \
118 "1: \n\t" \
119
120#define get_cabac_inline get_cabac_inline_loongarch
121static av_always_inline
123{
124 int64_t tmp0, tmp1, tmp2, bit;
125
126 __asm__ volatile (
127#if UNCHECKED_BITSTREAM_READER
129#else
131#endif
132 : [bit]"=&r"(bit), [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2),
133 [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
134 [c_bytestream]"+&r"(c->bytestream)
135 : [state]"r"(state), [tables]"r"(ff_h264_cabac_tables),
136#if !UNCHECKED_BITSTREAM_READER
137 [c_bytestream_end]"r"(c->bytestream_end),
138#endif
139 [lps_off]"i"(H264_LPS_RANGE_OFFSET),
140 [mlps_off]"i"(H264_MLPS_STATE_OFFSET + 128),
141 [norm_off]"i"(H264_NORM_SHIFT_OFFSET),
142 [cabac_mask]"r"(CABAC_MASK)
143 : "memory"
144 );
145
146 return bit;
147}
148
149#define get_cabac_bypass get_cabac_bypass_loongarch
151{
152 int64_t tmp0, tmp1, tmp2;
153 int res = 0;
154 __asm__ volatile(
155 "slli.d %[c_low], %[c_low], 0x01 \n\t"
156 "and %[tmp0], %[c_low], %[cabac_mask] \n\t"
157 "bnez %[tmp0], 1f \n\t"
158 "ld.hu %[tmp1], %[c_bytestream], 0x0 \n\t"
159#if UNCHECKED_BITSTREAM_READER
160 "addi.d %[c_bytestream], %[c_bytestream], 0x02 \n\t"
161#else
162 "slt %[tmp0], %[c_bytestream], %[c_bytestream_end] \n\t"
163 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t"
164 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t"
165#endif
166 "revb.2h %[tmp1], %[tmp1] \n\t"
167 "slli.d %[tmp1], %[tmp1], 0x01 \n\t"
168 "sub.d %[tmp1], %[tmp1], %[cabac_mask] \n\t"
169 "add.d %[c_low], %[c_low], %[tmp1] \n\t"
170 "1: \n\t"
171 "slli.d %[tmp1], %[c_range], 0x11 \n\t"
172 "slt %[tmp0], %[c_low], %[tmp1] \n\t"
173 "sub.d %[tmp1], %[c_low], %[tmp1] \n\t"
174 "masknez %[tmp2], %[one], %[tmp0] \n\t"
175 "maskeqz %[res], %[res], %[tmp0] \n\t"
176 "or %[res], %[res], %[tmp2] \n\t"
177 "masknez %[tmp2], %[tmp1], %[tmp0] \n\t"
178 "maskeqz %[c_low], %[c_low], %[tmp0] \n\t"
179 "or %[c_low], %[c_low], %[tmp2] \n\t"
180 : [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2),
181 [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
182 [c_bytestream]"+&r"(c->bytestream), [res]"+&r"(res)
183 : [cabac_mask]"r"(CABAC_MASK),
184#if !UNCHECKED_BITSTREAM_READER
185 [c_bytestream_end]"r"(c->bytestream_end),
186#endif
187 [one]"r"(0x01)
188 : "memory"
189 );
190 return res;
191}
192
193#define get_cabac_bypass_sign get_cabac_bypass_sign_loongarch
194static av_always_inline
196{
197 int64_t tmp0, tmp1;
198 int res = val;
199 __asm__ volatile(
200 "slli.d %[c_low], %[c_low], 0x01 \n\t"
201 "and %[tmp0], %[c_low], %[cabac_mask] \n\t"
202 "bnez %[tmp0], 1f \n\t"
203 "ld.hu %[tmp1], %[c_bytestream], 0x0 \n\t"
204#if UNCHECKED_BITSTREAM_READER
205 "addi.d %[c_bytestream], %[c_bytestream], 0x02 \n\t"
206#else
207 "slt %[tmp0], %[c_bytestream], %[c_bytestream_end] \n\t"
208 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t"
209 "add.d %[c_bytestream], %[c_bytestream], %[tmp0] \n\t"
210#endif
211 "revb.2h %[tmp1], %[tmp1] \n\t"
212 "slli.d %[tmp1], %[tmp1], 0x01 \n\t"
213 "sub.d %[tmp1], %[tmp1], %[cabac_mask] \n\t"
214 "add.d %[c_low], %[c_low], %[tmp1] \n\t"
215 "1: \n\t"
216 "slli.d %[tmp1], %[c_range], 0x11 \n\t"
217 "slt %[tmp0], %[c_low], %[tmp1] \n\t"
218 "sub.d %[tmp1], %[c_low], %[tmp1] \n\t"
219 "masknez %[tmp1], %[tmp1], %[tmp0] \n\t"
220 "maskeqz %[c_low], %[c_low], %[tmp0] \n\t"
221 "or %[c_low], %[c_low], %[tmp1] \n\t"
222 "sub.d %[tmp1], %[zero], %[res] \n\t"
223 "maskeqz %[tmp1], %[tmp1], %[tmp0] \n\t"
224 "masknez %[res], %[res], %[tmp0] \n\t"
225 "or %[res], %[res], %[tmp1] \n\t"
226 : [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [res]"+&r"(res),
227 [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
228 [c_bytestream]"+&r"(c->bytestream)
229 : [cabac_mask]"r"(CABAC_MASK),
230#if !UNCHECKED_BITSTREAM_READER
231 [c_bytestream_end]"r"(c->bytestream_end),
232#endif
233 [zero]"r"(0x0)
234 : "memory"
235 );
236
237 return res;
238}
239#endif /* AVCODEC_LOONGARCH_CABAC_H */
static double val(void *priv, double ch)
Definition aeval.c:77
__asm__(".macro parse_r var r\n\t" "\\var = -1\n\t" _IFC_REG(0) _IFC_REG(1) _IFC_REG(2) _IFC_REG(3) _IFC_REG(4) _IFC_REG(5) _IFC_REG(6) _IFC_REG(7) _IFC_REG(8) _IFC_REG(9) _IFC_REG(10) _IFC_REG(11) _IFC_REG(12) _IFC_REG(13) _IFC_REG(14) _IFC_REG(15) _IFC_REG(16) _IFC_REG(17) _IFC_REG(18) _IFC_REG(19) _IFC_REG(20) _IFC_REG(21) _IFC_REG(22) _IFC_REG(23) _IFC_REG(24) _IFC_REG(25) _IFC_REG(26) _IFC_REG(27) _IFC_REG(28) _IFC_REG(29) _IFC_REG(30) _IFC_REG(31) ".iflt \\var\n\t" ".error \"Unable to parse register name \\r\"\n\t" ".endif\n\t" ".endm")
Context Adaptive Binary Arithmetic Coder.
#define CABAC_MASK
Definition cabac.h:39
#define H264_LPS_RANGE_OFFSET
Definition cabac.h:34
#define H264_MLPS_STATE_OFFSET
Definition cabac.h:35
#define H264_NORM_SHIFT_OFFSET
Definition cabac.h:33
const uint8_t ff_h264_cabac_tables[512+4 *2 *64+4 *64+63]
#define bit(string, value)
Definition cbs_mpeg2.c:56
long long int64_t
Definition coverity.c:34
static struct @346255127015250356166251341105367306144006377143 state
static int zero(InterplayACMContext *s, unsigned ind, unsigned col)
Macro definitions for various function/variable attributes.
#define av_always_inline
Definition attributes.h:72
static av_always_inline int get_cabac_bypass_loongarch(CABACContext *c)
Definition cabac.h:150
#define GET_CABAC_LOONGARCH_UNCBSR
Definition cabac.h:32
static av_always_inline int get_cabac_bypass_sign_loongarch(CABACContext *c, int val)
Definition cabac.h:195
#define GET_CABAC_LOONGARCH
Definition cabac.h:74
static av_always_inline int get_cabac_inline_loongarch(CABACContext *c, uint8_t *const state)
Definition cabac.h:122
static const uint8_t *const tables[]
static double c[64]