]> git.sesse.net Git - vlc/blob - modules/arm_neon/nv21_rgb.S
handle the underscore prefix for some ARM ABI in arm_neon
[vlc] / modules / arm_neon / nv21_rgb.S
1  @*****************************************************************************
2  @ nv21_rgb.S : ARM NEONv1 NV21 to RGB chroma conversion
3  @*****************************************************************************
4  @ Copyright (C) 2011 Sébastien Toque
5  @                    Rémi Denis-Courmont
6  @
7  @ This program is free software; you can redistribute it and/or modify
8  @ it under the terms of the GNU General Public License as published by
9  @ the Free Software Foundation; either version 2 of the License, or
10  @ (at your option) any later version.
11  @
12  @ This program is distributed in the hope that it will be useful,
13  @ but WITHOUT ANY WARRANTY; without even the implied warranty of
14  @ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  @ GNU General Public License for more details.
16  @
17  @ You should have received a copy of the GNU General Public License
18  @ along with this program; if not, write to the Free Software Foundation,
19  @ Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
20  @****************************************************************************/
21
22         .fpu neon
23         .text
24
25 /* ARM */
26 #define O1      r0
27 #define O2      r1
28 #define WIDTH   r2
29 #define HEIGHT  r3
30 #define Y1      r4
31 #define Y2      r5
32 #define U       r6
33 #define V       r7
34 #define YPITCH  r8
35 #define OPAD    r10
36 #define YPAD    r11
37 #define COUNT   ip
38 #define OPITCH  lr
39
40 /* NEON */
41 #define coefY   D0
42 #define coefRV  D1
43 #define coefGU  D2
44 #define coefGV  D3
45 #define coefBU  D4
46 #define Rc      Q3
47 #define Gc      Q4
48 #define Bc      Q5
49
50 #define u       D24
51 #define v       D25
52 #define y1      D28
53 #define y2      D29
54
55 #define chro_r  Q6
56 #define chro_g  Q7
57 #define chro_b  Q8
58 #define red             Q9
59 #define green   Q10
60 #define blue    Q11
61 #define lumi    Q15
62
63 #define red1    D24
64 #define green1  D25
65 #define blue1   D26
66 #define alpha1  D27
67 #define red2    D28
68 #define green2  D29
69 #define blue2   D30
70 #define alpha2  D31
71
72 coefficients:
73     .short  -15872
74     .short    4992
75     .short  -18432
76
77         .align
78         .global nv21_rgb_neon
79         .type   nv21_rgb_neon, %function
80 nv21_rgb_neon:
81         push            {r4-r8,r10-r11,lr}
82         vpush           {q4-q7}
83
84         /* load arguments */
85         ldmia           r0,     {O1, OPITCH}
86         ldmia           r1,     {Y1, U, V, YPITCH}
87
88         /* round the width to be a multiple of 16 */
89         ands            OPAD, WIDTH, #15
90         sub                     WIDTH, WIDTH, OPAD
91         addne           WIDTH, WIDTH, #16
92
93         /* init constants (scale value by 64) */
94         vmov.u8         coefY, #74
95         vmov.u8         coefRV, #115
96         vmov.u8         coefGU, #14
97         vmov.u8         coefGV, #34
98         vmov.u8         coefBU, #135
99         adr                     OPAD, coefficients
100         vld1.s16        {d6[], d7[]}, [OPAD]!
101         vld1.s16        {d8[], d9[]}, [OPAD]!
102         vld1.s16        {d10[], d11[]}, [OPAD]!
103         vmov.u8         alpha1, #255
104
105         /* init padding */
106         cmp                     HEIGHT, #0
107         sub                     OPAD,   OPITCH, WIDTH, lsl #2
108         sub                     YPAD,   YPITCH, WIDTH
109
110 loop_row:
111         movgts  COUNT,  WIDTH
112         add             O2,     O1,     OPITCH
113         add             Y2,     Y1,     YPITCH
114         /* exit if all rows have been processed */
115         vpople  {q4-q7}
116         pople   {r4-r8,r10-r11,pc}
117
118 loop_col:
119
120         /* Common U & V */
121
122         vld2.u8 {u,v}, [U,:128]!
123
124         vmull.u8        chro_r, u, coefRV
125         vmull.u8        chro_g, v, coefGU
126         vmlal.u8        chro_g, u, coefGV
127         vmull.u8        chro_b, v, coefBU
128
129         vadd.s16        chro_r, Rc, chro_r
130         vsub.s16        chro_g, Gc, chro_g
131         vadd.s16        chro_b, Bc, chro_b
132
133         pld     [U]
134
135         /* Y Top Row */
136         vld2.u8 {y1,y2}, [Y1,:128]!
137
138         /* y1 : chrominance + luminance, then clamp (divide by 64) */
139         vmull.u8        lumi, y1, coefY
140         vqadd.s16       red, lumi, chro_r
141         vqadd.s16       green, lumi, chro_g
142         vqadd.s16       blue, lumi, chro_b
143         vqrshrun.s16    red1, red, #6
144         vqrshrun.s16    green1, green, #6
145         vqrshrun.s16    blue1, blue, #6
146
147         /* y2 : chrominance + luminance, then clamp (divide by 64) */
148         vmull.u8        lumi, y2, coefY
149         vqadd.s16       red, lumi, chro_r
150         vqadd.s16       green, lumi, chro_g
151         vqadd.s16       blue, lumi, chro_b
152         vqrshrun.s16    red2, red, #6
153         vqrshrun.s16    green2, green, #6
154         vqrshrun.s16    blue2, blue, #6
155
156         pld     [Y1]
157
158         vmov.u8 alpha2, #255
159         vzip.u8 red1, red2
160         vzip.u8 green1, green2
161         vzip.u8 blue1, blue2
162
163         vst4.u8         {red1,green1,blue1,alpha1}, [O1,:128]!
164         vst4.u8         {red2,green2,blue2,alpha2}, [O1,:128]!
165
166         /* Y Bottom Row */
167         vld2.u8 {y1,y2}, [Y2,:128]!
168
169         /* y1 : chrominance + luminance, then clamp (divide by 64) */
170         vmull.u8        lumi, y1, coefY
171         vqadd.s16       red, lumi, chro_r
172         vqadd.s16       green, lumi, chro_g
173         vqadd.s16       blue, lumi, chro_b
174         vqrshrun.s16    red1, red, #6
175         vqrshrun.s16    green1, green, #6
176         vqrshrun.s16    blue1, blue, #6
177
178         /* y2 : chrominance + luminance, then clamp (divide by 64) */
179         vmull.u8        lumi, y2, coefY
180         vqadd.s16       red, lumi, chro_r
181         vqadd.s16       green, lumi, chro_g
182         vqadd.s16       blue, lumi, chro_b
183         vqrshrun.s16    red2, red, #6
184         vqrshrun.s16    green2, green, #6
185         vqrshrun.s16    blue2, blue, #6
186
187         pld     [Y2]
188
189         vmov.u8 alpha2, #255
190         vzip.u8 red1, red2
191         vzip.u8 green1, green2
192         vzip.u8 blue1, blue2
193
194         vst4.u8         {red1,green1,blue1,alpha1}, [O2,:128]!
195         vst4.u8         {red2,green2,blue2,alpha2}, [O2,:128]!
196
197         /* next columns (x16) */
198         subs    COUNT,  COUNT,  #16
199         bgt             loop_col
200
201         /* next rows (x2) */
202         subs    HEIGHT, #2
203         add             O1,     O2,     OPAD
204         add             Y1,     Y2,     YPAD
205         add             U,      U,      YPAD
206         b               loop_row