• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
get_cabac_inline_mips(CABACContext * c,uint8_t * const state)34 static 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
get_cabac_bypass_mips(CABACContext * c)124 static 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
get_cabac_bypass_sign_mips(CABACContext * c,int val)176 static 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