bfin: Move all assembly declarations only used within one .c file there
[ffmpeg.git] / libavcodec / bfin / dsputil_bfin.c
1 /*
2  * BlackFin DSPUTILS
3  *
4  * Copyright (C) 2007 Marc Hoffman <marc.hoffman@analog.com>
5  * Copyright (c) 2006 Michael Benjamin <michael.benjamin@analog.com>
6  *
7  * This file is part of Libav.
8  *
9  * Libav is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * Libav is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with Libav; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 #include <stdint.h>
25
26 #include "config.h"
27 #include "libavutil/attributes.h"
28 #include "libavutil/bfin/attributes.h"
29 #include "libavcodec/avcodec.h"
30 #include "libavcodec/dsputil.h"
31
32 void ff_bfin_idct(int16_t *block) attribute_l1_text;
33 void ff_bfin_fdct(int16_t *block) attribute_l1_text;
34
35 void ff_bfin_add_pixels_clamped(const int16_t *block, uint8_t *dest,
36                                 int line_size) attribute_l1_text;
37 void ff_bfin_put_pixels_clamped(const int16_t *block, uint8_t *dest,
38                                 int line_size) attribute_l1_text;
39
40 void ff_bfin_diff_pixels(int16_t *block, const uint8_t *s1, const uint8_t *s2,
41                          int stride)  attribute_l1_text;
42 void ff_bfin_get_pixels(int16_t *restrict block, const uint8_t *pixels,
43                         int line_size) attribute_l1_text;
44
45 int ff_bfin_pix_norm1(uint8_t *pix, int line_size) attribute_l1_text;
46 int ff_bfin_pix_sum(uint8_t *p, int stride) attribute_l1_text;
47
48 int ff_bfin_z_sad8x8(uint8_t *blk1, uint8_t *blk2, int dsz,
49                      int line_size, int h) attribute_l1_text;
50 int ff_bfin_z_sad16x16(uint8_t *blk1, uint8_t *blk2, int dsz,
51                        int line_size, int h) attribute_l1_text;
52
53 int ff_bfin_sse4(void *v, uint8_t *pix1, uint8_t *pix2,
54                  int line_size, int h) attribute_l1_text;
55 int ff_bfin_sse8(void *v, uint8_t *pix1, uint8_t *pix2,
56                  int line_size, int h) attribute_l1_text;
57 int ff_bfin_sse16(void *v, uint8_t *pix1, uint8_t *pix2,
58                   int line_size, int h) attribute_l1_text;
59
60 static void bfin_idct_add(uint8_t *dest, int line_size, int16_t *block)
61 {
62     ff_bfin_idct(block);
63     ff_bfin_add_pixels_clamped(block, dest, line_size);
64 }
65
66 static void bfin_idct_put(uint8_t *dest, int line_size, int16_t *block)
67 {
68     ff_bfin_idct(block);
69     ff_bfin_put_pixels_clamped(block, dest, line_size);
70 }
71
72 static void bfin_clear_blocks(int16_t *blocks)
73 {
74     // This is just a simple memset.
75     __asm__ ("P0=192; "
76              "I0=%0;  "
77              "R0=0;   "
78              "LSETUP(clear_blocks_blkfn_lab,clear_blocks_blkfn_lab)LC0=P0;"
79              "clear_blocks_blkfn_lab:"
80              "[I0++]=R0;"
81              ::"a" (blocks) : "P0", "I0", "R0");
82 }
83
84 static int bfin_pix_abs16(void *c, uint8_t *blk1, uint8_t *blk2,
85                           int line_size, int h)
86 {
87     return ff_bfin_z_sad16x16(blk1, blk2, line_size, line_size, h);
88 }
89
90 static uint8_t vtmp_blk[256] attribute_l1_data_b;
91
92 static int bfin_pix_abs16_x2(void *c, uint8_t *blk1, uint8_t *blk2,
93                              int line_size, int h)
94 {
95     ff_bfin_put_pixels16uc(vtmp_blk, blk2, blk2 + 1, 16, line_size, h);
96     return ff_bfin_z_sad16x16(blk1, vtmp_blk, line_size, 16, h);
97 }
98
99 static int bfin_pix_abs16_y2(void *c, uint8_t *blk1, uint8_t *blk2,
100                              int line_size, int h)
101 {
102     ff_bfin_put_pixels16uc(vtmp_blk, blk2, blk2 + line_size, 16, line_size, h);
103     return ff_bfin_z_sad16x16(blk1, vtmp_blk, line_size, 16, h);
104 }
105
106 static int bfin_pix_abs16_xy2(void *c, uint8_t *blk1, uint8_t *blk2,
107                               int line_size, int h)
108 {
109     ff_bfin_z_put_pixels16_xy2(vtmp_blk, blk2, 16, line_size, h);
110     return ff_bfin_z_sad16x16(blk1, vtmp_blk, line_size, 16, h);
111 }
112
113 static int bfin_pix_abs8(void *c, uint8_t *blk1, uint8_t *blk2,
114                          int line_size, int h)
115 {
116     return ff_bfin_z_sad8x8(blk1, blk2, line_size, line_size, h);
117 }
118
119 static int bfin_pix_abs8_x2(void *c, uint8_t *blk1, uint8_t *blk2,
120                             int line_size, int h)
121 {
122     ff_bfin_put_pixels8uc(vtmp_blk, blk2, blk2 + 1, 8, line_size, h);
123     return ff_bfin_z_sad8x8(blk1, vtmp_blk, line_size, 8, h);
124 }
125
126 static int bfin_pix_abs8_y2(void *c, uint8_t *blk1, uint8_t *blk2,
127                             int line_size, int h)
128 {
129     ff_bfin_put_pixels8uc(vtmp_blk, blk2, blk2 + line_size, 8, line_size, h);
130     return ff_bfin_z_sad8x8(blk1, vtmp_blk, line_size, 8, h);
131 }
132
133 static int bfin_pix_abs8_xy2(void *c, uint8_t *blk1, uint8_t *blk2,
134                              int line_size, int h)
135 {
136     ff_bfin_z_put_pixels8_xy2(vtmp_blk, blk2, 8, line_size, h);
137     return ff_bfin_z_sad8x8(blk1, vtmp_blk, line_size, 8, h);
138 }
139
140 /*
141  * decoder optimization
142  * start on 2/11 100 frames of 352x240@25 compiled with no optimization -g debugging
143  * 9.824s ~ 2.44x off
144  * 6.360s ~ 1.58x off with -O2
145  * 5.740s ~ 1.43x off with idcts
146  *
147  * 2.64s    2/20 same sman.mp4 decode only
148  */
149
150 av_cold void ff_dsputil_init_bfin(DSPContext *c, AVCodecContext *avctx)
151 {
152     const int high_bit_depth = avctx->bits_per_raw_sample > 8;
153
154     c->diff_pixels = ff_bfin_diff_pixels;
155
156     c->put_pixels_clamped = ff_bfin_put_pixels_clamped;
157     c->add_pixels_clamped = ff_bfin_add_pixels_clamped;
158
159     if (!high_bit_depth)
160         c->get_pixels = ff_bfin_get_pixels;
161
162     c->clear_blocks = bfin_clear_blocks;
163
164     c->pix_sum   = ff_bfin_pix_sum;
165     c->pix_norm1 = ff_bfin_pix_norm1;
166
167     c->sad[0] = bfin_pix_abs16;
168     c->sad[1] = bfin_pix_abs8;
169
170     /* TODO [0] 16  [1] 8 */
171     c->pix_abs[0][0] = bfin_pix_abs16;
172     c->pix_abs[0][1] = bfin_pix_abs16_x2;
173     c->pix_abs[0][2] = bfin_pix_abs16_y2;
174     c->pix_abs[0][3] = bfin_pix_abs16_xy2;
175
176     c->pix_abs[1][0] = bfin_pix_abs8;
177     c->pix_abs[1][1] = bfin_pix_abs8_x2;
178     c->pix_abs[1][2] = bfin_pix_abs8_y2;
179     c->pix_abs[1][3] = bfin_pix_abs8_xy2;
180
181     c->sse[0] = ff_bfin_sse16;
182     c->sse[1] = ff_bfin_sse8;
183     c->sse[2] = ff_bfin_sse4;
184
185     if (avctx->bits_per_raw_sample <= 8) {
186         if (avctx->dct_algo == FF_DCT_AUTO)
187             c->fdct = ff_bfin_fdct;
188
189         if (avctx->idct_algo == FF_IDCT_AUTO) {
190             c->idct_permutation_type = FF_NO_IDCT_PERM;
191             c->idct                  = ff_bfin_idct;
192             c->idct_add              = bfin_idct_add;
193             c->idct_put              = bfin_idct_put;
194         }
195     }
196 }