xref: /third_party/ffmpeg/libavcodec/mips/cabac.h (revision cabdff1a)
1/*
2 * Loongson SIMD optimized h264chroma
3 *
4 * Copyright (c) 2018 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_MIPS_CABAC_H
26#define AVCODEC_MIPS_CABAC_H
27
28#include "libavutil/attributes.h"
29#include "libavcodec/cabac.h"
30#include "libavutil/mips/mmiutils.h"
31#include "config.h"
32
33#define get_cabac_inline get_cabac_inline_mips
34static av_always_inline int get_cabac_inline_mips(CABACContext *c,
35                                                  uint8_t * const state){
36    mips_reg tmp0, tmp1, tmp2, bit;
37
38    __asm__ volatile (
39        "lbu          %[bit],        0(%[state])                   \n\t"
40        "and          %[tmp0],       %[c_range],     0xC0          \n\t"
41        PTR_SLL      "%[tmp0],       %[tmp0],        0x01          \n\t"
42        PTR_ADDU     "%[tmp0],       %[tmp0],        %[tables]     \n\t"
43        PTR_ADDU     "%[tmp0],       %[tmp0],        %[bit]        \n\t"
44        /* tmp1: RangeLPS */
45        "lbu          %[tmp1],       %[lps_off](%[tmp0])           \n\t"
46
47        PTR_SUBU     "%[c_range],    %[c_range],     %[tmp1]       \n\t"
48        PTR_SLL      "%[tmp0],       %[c_range],     0x11          \n\t"
49        "slt          %[tmp2],       %[tmp0],        %[c_low]      \n\t"
50        "beqz         %[tmp2],       1f                            \n\t"
51        "move         %[c_range],    %[tmp1]                       \n\t"
52        "not          %[bit],        %[bit]                        \n\t"
53        PTR_SUBU     "%[c_low],      %[c_low],       %[tmp0]       \n\t"
54
55        "1:                                                        \n\t"
56        /* tmp1: *state */
57        PTR_ADDU     "%[tmp0],       %[tables],      %[bit]        \n\t"
58        "lbu          %[tmp1],       %[mlps_off](%[tmp0])          \n\t"
59        /* tmp2: lps_mask */
60        PTR_ADDU     "%[tmp0],       %[tables],      %[c_range]    \n\t"
61        "lbu          %[tmp2],       %[norm_off](%[tmp0])          \n\t"
62
63        "sb           %[tmp1],       0(%[state])                   \n\t"
64        "and          %[bit],        %[bit],         0x01          \n\t"
65        PTR_SLL      "%[c_range],    %[c_range],     %[tmp2]       \n\t"
66        PTR_SLL      "%[c_low],      %[c_low],       %[tmp2]       \n\t"
67
68        "and          %[tmp1],       %[c_low],       %[cabac_mask] \n\t"
69        "bnez         %[tmp1],       1f                            \n\t"
70        PTR_ADDIU    "%[tmp0],       %[c_low],       -0X01         \n\t"
71        "xor          %[tmp0],       %[c_low],       %[tmp0]       \n\t"
72        PTR_SRA      "%[tmp0],       %[tmp0],        0x0f          \n\t"
73        PTR_ADDU     "%[tmp0],       %[tmp0],        %[tables]     \n\t"
74        /* tmp2: ff_h264_norm_shift[x >> (CABAC_BITS - 1)] */
75        "lbu          %[tmp2],       %[norm_off](%[tmp0])          \n\t"
76#if HAVE_BIGENDIAN
77        "lhu          %[tmp0],       0(%[c_bytestream])            \n\t"
78#else
79        "lhu          %[tmp0],       0(%[c_bytestream])            \n\t"
80#if HAVE_MIPS32R2 || HAVE_MIPS64R2
81        "wsbh         %[tmp0],       %[tmp0]                       \n\t"
82#else
83        "and          %[tmp1],      %[tmp0],         0xff00ff00    \n\t"
84        "srl          %[tmp1],      %[tmp1],         8             \n\t"
85        "and          %[tmp0],      %[tmp0],         0x00ff00ff    \n\t"
86        "sll          %[tmp0],      %[tmp0],         8             \n\t"
87        "or           %[tmp0],      %[tmp0],         %[tmp1]       \n\t"
88#endif
89#endif
90        PTR_SLL      "%[tmp0],       %[tmp0],        0x01          \n\t"
91        PTR_SUBU     "%[tmp0],       %[tmp0],        %[cabac_mask] \n\t"
92
93        "li           %[tmp1],       0x07                          \n\t"
94        PTR_SUBU     "%[tmp1],       %[tmp1],        %[tmp2]       \n\t"
95        PTR_SLL      "%[tmp0],       %[tmp0],        %[tmp1]       \n\t"
96        PTR_ADDU     "%[c_low],      %[c_low],       %[tmp0]       \n\t"
97
98#if UNCHECKED_BITSTREAM_READER
99        PTR_ADDIU    "%[c_bytestream], %[c_bytestream],     0x02                 \n\t"
100#else
101        "slt          %[tmp0],         %[c_bytestream],     %[c_bytestream_end]  \n\t"
102        PTR_ADDIU    "%[tmp2],         %[c_bytestream],     0x02                 \n\t"
103        "movn         %[c_bytestream], %[tmp2],             %[tmp0]              \n\t"
104#endif
105        "1:                                                        \n\t"
106    : [bit]"=&r"(bit), [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [tmp2]"=&r"(tmp2),
107      [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
108      [c_bytestream]"+&r"(c->bytestream)
109    : [state]"r"(state), [tables]"r"(ff_h264_cabac_tables),
110#if !UNCHECKED_BITSTREAM_READER
111      [c_bytestream_end]"r"(c->bytestream_end),
112#endif
113      [lps_off]"i"(H264_LPS_RANGE_OFFSET),
114      [mlps_off]"i"(H264_MLPS_STATE_OFFSET + 128),
115      [norm_off]"i"(H264_NORM_SHIFT_OFFSET),
116      [cabac_mask]"r"(CABAC_MASK)
117    : "memory"
118    );
119
120    return bit;
121}
122
123#define get_cabac_bypass get_cabac_bypass_mips
124static av_always_inline int get_cabac_bypass_mips(CABACContext *c)
125{
126    mips_reg tmp0, tmp1;
127    int res = 0;
128    __asm__ volatile(
129        PTR_SLL    "%[c_low],        %[c_low],        0x01                \n\t"
130        "and        %[tmp0],         %[c_low],        %[cabac_mask]       \n\t"
131        "bnez       %[tmp0],         1f                                   \n\t"
132#if HAVE_BIGENDIAN
133        "lhu        %[tmp1],         0(%[c_bytestream])                   \n\t"
134#else
135        "lhu        %[tmp1],         0(%[c_bytestream])                   \n\t"
136#if HAVE_MIPS32R2 || HAVE_MIPS64R2
137        "wsbh       %[tmp1],         %[tmp1]                              \n\t"
138#else
139        "and        %[tmp0],         %[tmp1],         0xff00ff00          \n\t"
140        "srl        %[tmp0],         %[tmp0],         8                   \n\t"
141        "and        %[tmp1],         %[tmp1],         0x00ff00ff          \n\t"
142        "sll        %[tmp1],         %[tmp1],         8                   \n\t"
143        "or         %[tmp1],         %[tmp1],         %[tmp0]             \n\t"
144#endif
145#endif
146        PTR_SLL    "%[tmp1],         %[tmp1],         0x01                \n\t"
147        PTR_SUBU   "%[tmp1],         %[tmp1],         %[cabac_mask]       \n\t"
148        PTR_ADDU   "%[c_low],        %[c_low],        %[tmp1]             \n\t"
149#if UNCHECKED_BITSTREAM_READER
150        PTR_ADDIU  "%[c_bytestream], %[c_bytestream], 0x02                \n\t"
151#else
152        "slt        %[tmp0],         %[c_bytestream], %[c_bytestream_end] \n\t"
153        PTR_ADDIU  "%[tmp1],         %[c_bytestream], 0x02                \n\t"
154        "movn       %[c_bytestream], %[tmp1],         %[tmp0]             \n\t"
155#endif
156        "1:                                                               \n\t"
157        PTR_SLL    "%[tmp1],         %[c_range],      0x11                \n\t"
158        "slt        %[tmp0],         %[c_low],        %[tmp1]             \n\t"
159        PTR_SUBU   "%[tmp1],         %[c_low],        %[tmp1]             \n\t"
160        "movz       %[res],          %[one],          %[tmp0]             \n\t"
161        "movz       %[c_low],        %[tmp1],         %[tmp0]             \n\t"
162        : [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [res]"+&r"(res),
163          [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
164          [c_bytestream]"+&r"(c->bytestream)
165        : [cabac_mask]"r"(CABAC_MASK),
166#if !UNCHECKED_BITSTREAM_READER
167          [c_bytestream_end]"r"(c->bytestream_end),
168#endif
169          [one]"r"(0x01)
170        : "memory"
171    );
172    return res;
173}
174
175#define get_cabac_bypass_sign get_cabac_bypass_sign_mips
176static av_always_inline int get_cabac_bypass_sign_mips(CABACContext *c, int val)
177{
178    mips_reg tmp0, tmp1;
179    int res = val;
180    __asm__ volatile(
181        PTR_SLL    "%[c_low],        %[c_low],        0x01                \n\t"
182        "and        %[tmp0],         %[c_low],        %[cabac_mask]       \n\t"
183        "bnez       %[tmp0],         1f                                   \n\t"
184#if HAVE_BIGENDIAN
185        "lhu        %[tmp1],         0(%[c_bytestream])                   \n\t"
186#else
187        "lhu        %[tmp1],         0(%[c_bytestream])                   \n\t"
188#if HAVE_MIPS32R2 || HAVE_MIPS64R2
189        "wsbh       %[tmp1],         %[tmp1]                              \n\t"
190#else
191        "and        %[tmp0],         %[tmp1],         0xff00ff00          \n\t"
192        "srl        %[tmp0],         %[tmp0],         8                   \n\t"
193        "and        %[tmp1],         %[tmp1],         0x00ff00ff          \n\t"
194        "sll        %[tmp1],         %[tmp1],         8                   \n\t"
195        "or         %[tmp1],         %[tmp1],         %[tmp0]             \n\t"
196#endif
197#endif
198        PTR_SLL    "%[tmp1],         %[tmp1],         0x01                \n\t"
199        PTR_SUBU   "%[tmp1],         %[tmp1],         %[cabac_mask]       \n\t"
200        PTR_ADDU   "%[c_low],        %[c_low],        %[tmp1]             \n\t"
201#if UNCHECKED_BITSTREAM_READER
202        PTR_ADDIU  "%[c_bytestream], %[c_bytestream], 0x02                \n\t"
203#else
204        "slt        %[tmp0],         %[c_bytestream], %[c_bytestream_end] \n\t"
205        PTR_ADDIU  "%[tmp1],         %[c_bytestream], 0x02                \n\t"
206        "movn       %[c_bytestream], %[tmp1],         %[tmp0]             \n\t"
207#endif
208        "1:                                                               \n\t"
209        PTR_SLL    "%[tmp1],         %[c_range],      0x11                \n\t"
210        "slt        %[tmp0],         %[c_low],        %[tmp1]             \n\t"
211        PTR_SUBU   "%[tmp1],         %[c_low],        %[tmp1]             \n\t"
212        "movz       %[c_low],        %[tmp1],         %[tmp0]             \n\t"
213        PTR_SUBU   "%[tmp1],         %[zero],         %[res]              \n\t"
214        "movn       %[res],          %[tmp1],         %[tmp0]             \n\t"
215        : [tmp0]"=&r"(tmp0), [tmp1]"=&r"(tmp1), [res]"+&r"(res),
216          [c_range]"+&r"(c->range), [c_low]"+&r"(c->low),
217          [c_bytestream]"+&r"(c->bytestream)
218        : [cabac_mask]"r"(CABAC_MASK),
219#if !UNCHECKED_BITSTREAM_READER
220          [c_bytestream_end]"r"(c->bytestream_end),
221#endif
222          [zero]"r"(0x0)
223        : "memory"
224    );
225
226    return res;
227}
228#endif /* AVCODEC_MIPS_CABAC_H */
229