fix build error
[platform/upstream/openblas.git] / kernel / mips / cscal_msa.c
1 /*******************************************************************************
2 Copyright (c) 2017, The OpenBLAS Project
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 1. Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 2. Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 3. Neither the name of the OpenBLAS project nor the names of
14 its contributors may be used to endorse or promote products
15 derived from this software without specific prior written permission.
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBLAS PROJECT OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *******************************************************************************/
27
28 #include "common.h"
29 #include "macros_msa.h"
30
31 /* This will shuffle the elements in 'in' vector as (mask needed :: 10 11 00 01)
32    0  1  2  3  =>  1  0  3  2 */
33 #define SHF_177   177
34
35 int CNAME(BLASLONG n, BLASLONG dummy0, BLASLONG dummy1, FLOAT da_r, FLOAT da_i,
36           FLOAT *x, BLASLONG inc_x, FLOAT *y, BLASLONG inc_y, FLOAT *dummy,
37           BLASLONG dummy2)
38 {
39     BLASLONG i, inc_x2;
40     FLOAT *px;
41     FLOAT tp0, tp1, tp2, tp3, f0, f1, f2, f3;
42     v4f32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
43     v4f32 d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11, d12, d13, d14, d15;
44     v4f32 da_i_vec, da_i_vec_neg, da_r_vec;
45
46     px = x;
47
48     if (1 == inc_x)
49     {
50         if ((0.0 == da_r) && (0.0 == da_i))
51         {
52             v4f32 zero_v = __msa_cast_to_vector_float(0);
53             zero_v = (v4f32) __msa_insert_w((v4i32) zero_v, 0, 0.0);
54             zero_v = (v4f32) __msa_insert_w((v4i32) zero_v, 1, 0.0);
55             zero_v = (v4f32) __msa_insert_w((v4i32) zero_v, 2, 0.0);
56             zero_v = (v4f32) __msa_insert_w((v4i32) zero_v, 3, 0.0);
57
58             for (i = (n >> 5); i--;)
59             {
60                 ST_SP8_INC(zero_v, zero_v, zero_v, zero_v, zero_v, zero_v,
61                            zero_v, zero_v, x, 4);
62                 ST_SP8_INC(zero_v, zero_v, zero_v, zero_v, zero_v, zero_v,
63                            zero_v, zero_v, x, 4);
64             }
65
66             if (n & 31)
67             {
68                 if (n & 16)
69                 {
70                     ST_SP8_INC(zero_v, zero_v, zero_v, zero_v, zero_v, zero_v,
71                                zero_v, zero_v, x, 4);
72                 }
73
74                 if (n & 8)
75                 {
76                     ST_SP4_INC(zero_v, zero_v, zero_v, zero_v, x, 4);
77                 }
78
79                 if (n & 4)
80                 {
81                     ST_SP2_INC(zero_v, zero_v, x, 4);
82                 }
83
84                 if (n & 2)
85                 {
86                     ST_SP(zero_v, x); x += 4;
87                 }
88
89                 if (n & 1)
90                 {
91                     *x = 0; x += 1;
92                     *x = 0;
93                 }
94             }
95         }
96         else if (0.0 == da_r)
97         {
98             da_i_vec = COPY_FLOAT_TO_VECTOR(da_i);
99             da_i_vec_neg = -da_i_vec;
100             da_i_vec = (v4f32) __msa_ilvev_w((v4i32) da_i_vec_neg, (v4i32) da_i_vec);
101
102             if (n > 31)
103             {
104                 FLOAT *x_pref;
105                 BLASLONG pref_offset;
106
107                 pref_offset = (BLASLONG)x & (L1_DATA_LINESIZE - 1);
108                 if (pref_offset > 0)
109                 {
110                     pref_offset = L1_DATA_LINESIZE - pref_offset;
111                     pref_offset = pref_offset / sizeof(FLOAT);
112                 }
113                 x_pref = x + pref_offset + 64 + 32;
114
115                 LD_SP8_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7);
116                 for (i = (n >> 5)- 1; i--;)
117                 {
118                     PREF_OFFSET(x_pref, 0);
119                     PREF_OFFSET(x_pref, 32);
120                     PREF_OFFSET(x_pref, 64);
121                     PREF_OFFSET(x_pref, 96);
122                     PREF_OFFSET(x_pref, 128);
123                     PREF_OFFSET(x_pref, 160);
124                     PREF_OFFSET(x_pref, 192);
125                     PREF_OFFSET(x_pref, 224);
126                     x_pref += 64;
127
128                     x8 = LD_SP(px); px += 4;
129                     x0 *= da_i_vec;
130                     x9 = LD_SP(px); px += 4;
131                     x1 *= da_i_vec;
132                     x10 = LD_SP(px); px += 4;
133                     x2 *= da_i_vec;
134                     x11 = LD_SP(px); px += 4;
135                     x3 *= da_i_vec;
136                     x12 = LD_SP(px); px += 4;
137                     x4 *= da_i_vec;
138                     x13 = LD_SP(px); px += 4;
139                     x5 *= da_i_vec;
140                     x0 = (v4f32) __msa_shf_w((v4i32) x0, SHF_177);
141                     x14 = LD_SP(px); px += 4;
142                     x6 *= da_i_vec;
143                     x1 = (v4f32) __msa_shf_w((v4i32) x1, SHF_177);
144                     x15 = LD_SP(px); px += 4;
145                     x7 *= da_i_vec;
146                     x2 = (v4f32) __msa_shf_w((v4i32) x2, SHF_177);
147                     x8 *= da_i_vec;
148                     x3 = (v4f32) __msa_shf_w((v4i32) x3, SHF_177);
149                     ST_SP(x0, x); x += 4;
150                     x9 *= da_i_vec;
151                     x4 = (v4f32) __msa_shf_w((v4i32) x4, SHF_177);
152                     ST_SP(x1, x); x += 4;
153                     x10 *= da_i_vec;
154                     x5 = (v4f32) __msa_shf_w((v4i32) x5, SHF_177);
155                     ST_SP(x2, x); x += 4;
156                     x11 *= da_i_vec;
157                     x6 = (v4f32) __msa_shf_w((v4i32) x6, SHF_177);
158                     ST_SP(x3, x); x += 4;
159                     x12 *= da_i_vec;
160                     x7 = (v4f32) __msa_shf_w((v4i32) x7, SHF_177);
161                     ST_SP(x4, x); x += 4;
162                     x13 *= da_i_vec;
163                     x8 = (v4f32) __msa_shf_w((v4i32) x8, SHF_177);
164                     ST_SP(x5, x); x += 4;
165                     x14 *= da_i_vec;
166                     x9 = (v4f32) __msa_shf_w((v4i32) x9, SHF_177);
167                     ST_SP(x6, x); x += 4;
168                     x15 *= da_i_vec;
169                     x10 = (v4f32) __msa_shf_w((v4i32) x10, SHF_177);
170                     ST_SP(x7, x); x += 4;
171                     x11 = (v4f32) __msa_shf_w((v4i32) x11, SHF_177);
172                     ST_SP(x8, x); x += 4;
173                     x0 = LD_SP(px); px += 4;
174                     x12 = (v4f32) __msa_shf_w((v4i32) x12, SHF_177);
175                     ST_SP(x9, x); x += 4;
176                     x1 = LD_SP(px); px += 4;
177                     x13 = (v4f32) __msa_shf_w((v4i32) x13, SHF_177);
178                     ST_SP(x10, x); x += 4;
179                     x2 = LD_SP(px); px += 4;
180                     x14 = (v4f32) __msa_shf_w((v4i32) x14, SHF_177);
181                     ST_SP(x11, x); x += 4;
182                     x3 = LD_SP(px); px += 4;
183                     x15 = (v4f32) __msa_shf_w((v4i32) x15, SHF_177);
184                     ST_SP(x12, x); x += 4;
185                     x4 = LD_SP(px); px += 4;
186                     ST_SP(x13, x); x += 4;
187                     x5 = LD_SP(px); px += 4;
188                     ST_SP(x14, x); x += 4;
189                     x6 = LD_SP(px); px += 4;
190                     ST_SP(x15, x); x += 4;
191                     x7 = LD_SP(px); px += 4;
192                 }
193
194                 LD_SP8_INC(px, 4, x8, x9, x10, x11, x12, x13, x14, x15);
195                 MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
196                      x0, x1, x2, x3);
197                 MUL4(x4, da_i_vec, x5, da_i_vec, x6, da_i_vec, x7, da_i_vec,
198                      x4, x5, x6, x7);
199                 MUL4(x8, da_i_vec, x9, da_i_vec, x10, da_i_vec, x11, da_i_vec,
200                      x8, x9, x10, x11);
201                 MUL4(x12, da_i_vec, x13, da_i_vec, x14, da_i_vec, x15, da_i_vec,
202                      x12, x13, x14, x15);
203                 SHF_W4_SP(x0, x1, x2, x3, x0, x1, x2, x3, SHF_177);
204                 SHF_W4_SP(x4, x5, x6, x7, x4, x5, x6, x7, SHF_177);
205                 SHF_W4_SP(x8, x9, x10, x11, x8, x9, x10, x11, SHF_177);
206                 SHF_W4_SP(x12, x13, x14, x15, x12, x13, x14, x15, SHF_177);
207                 ST_SP16_INC(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11,
208                             x12, x13, x14, x15, x, 4);
209             }
210
211             if (n & 31)
212             {
213                 if (n & 16)
214                 {
215                     LD_SP8_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7);
216                     MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
217                          x0, x1, x2, x3);
218                     MUL4(x4, da_i_vec, x5, da_i_vec, x6, da_i_vec, x7, da_i_vec,
219                          x4, x5, x6, x7);
220                     SHF_W4_SP(x0, x1, x2, x3, x0, x1, x2, x3, SHF_177);
221                     SHF_W4_SP(x4, x5, x6, x7, x4, x5, x6, x7, SHF_177);
222                     ST_SP8_INC(x0, x1, x2, x3, x4, x5, x6, x7, x, 4);
223                 }
224
225                 if (n & 8)
226                 {
227                     LD_SP4_INC(px, 4, x0, x1, x2, x3);
228                     MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
229                          x0, x1, x2, x3);
230                     SHF_W4_SP(x0, x1, x2, x3, x0, x1, x2, x3, SHF_177);
231                     ST_SP4_INC(x0, x1, x2, x3, x, 4);
232                 }
233
234                 if (n & 4)
235                 {
236                     LD_SP2_INC(px, 4, x0, x1);
237                     MUL2(x0, da_i_vec, x1, da_i_vec, x0, x1);
238                     SHF_W2_SP(x0, x1, x0, x1, SHF_177);
239                     ST_SP2_INC(x0, x1, x, 4);
240                 }
241
242                 if (n & 2)
243                 {
244                     LD_GP4_INC(px, 1, f0, f1, f2, f3);
245                     MUL4(f0, da_i, f1, -da_i, f2, da_i, f3, -da_i,
246                          f0, f1, f2, f3);
247                     ST_GP4_INC(f1, f0, f3, f2, x, 1);
248                 }
249
250                 if (n & 1)
251                 {
252                     LD_GP2_INC(px, 1, f0, f1);
253                     MUL2(f0, da_i, f1, -da_i, f0, f1);
254                     ST_GP2_INC(f1, f0, x, 1);
255                 }
256             }
257         }
258         else if (0.0 == da_i)
259         {
260             da_r_vec = COPY_FLOAT_TO_VECTOR(da_r);
261
262             if (n > 31)
263             {
264                 FLOAT *x_pref;
265                 BLASLONG pref_offset;
266
267                 pref_offset = (BLASLONG)x & (L1_DATA_LINESIZE - 1);
268                 if (pref_offset > 0)
269                 {
270                     pref_offset = L1_DATA_LINESIZE - pref_offset;
271                     pref_offset = pref_offset / sizeof(FLOAT);
272                 }
273                 x_pref = x + pref_offset + 64 + 32;
274
275                 LD_SP8_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7);
276                 for (i = (n >> 5)- 1; i--;)
277                 {
278                     PREF_OFFSET(x_pref, 0);
279                     PREF_OFFSET(x_pref, 32);
280                     PREF_OFFSET(x_pref, 64);
281                     PREF_OFFSET(x_pref, 96);
282                     PREF_OFFSET(x_pref, 128);
283                     PREF_OFFSET(x_pref, 160);
284                     PREF_OFFSET(x_pref, 192);
285                     PREF_OFFSET(x_pref, 224);
286                     x_pref += 64;
287
288                     x8 = LD_SP(px); px += 4;
289                     x0 *= da_r_vec;
290                     x9 = LD_SP(px); px += 4;
291                     x1 *= da_r_vec;
292                     x10 = LD_SP(px); px += 4;
293                     x2 *= da_r_vec;
294                     x11 = LD_SP(px); px += 4;
295                     x3 *= da_r_vec;
296                     x12 = LD_SP(px); px += 4;
297                     x4 *= da_r_vec;
298                     x13 = LD_SP(px); px += 4;
299                     x5 *= da_r_vec;
300                     ST_SP(x0, x); x += 4;
301                     x14 = LD_SP(px); px += 4;
302                     x6 *= da_r_vec;
303                     ST_SP(x1, x); x += 4;
304                     x15 = LD_SP(px); px += 4;
305                     x7 *= da_r_vec;
306                     ST_SP(x2, x); x += 4;
307                     x8 *= da_r_vec;
308                     ST_SP(x3, x); x += 4;
309                     x9 *= da_r_vec;
310                     ST_SP(x4, x); x += 4;
311                     x10 *= da_r_vec;
312                     ST_SP(x5, x); x += 4;
313                     x11 *= da_r_vec;
314                     ST_SP(x6, x); x += 4;
315                     x12 *= da_r_vec;
316                     ST_SP(x7, x); x += 4;
317                     x13 *= da_r_vec;
318                     ST_SP(x8, x); x += 4;
319                     x0 = LD_SP(px); px += 4;
320                     x14 *= da_r_vec;
321                     ST_SP(x9, x); x += 4;
322                     x1 = LD_SP(px); px += 4;
323                     x15 *= da_r_vec;
324                     ST_SP(x10, x); x += 4;
325                     x2 = LD_SP(px); px += 4;
326                     ST_SP(x11, x); x += 4;
327                     x3 = LD_SP(px); px += 4;
328                     ST_SP(x12, x); x += 4;
329                     x4 = LD_SP(px); px += 4;
330                     ST_SP(x13, x); x += 4;
331                     x5 = LD_SP(px); px += 4;
332                     ST_SP(x14, x); x += 4;
333                     x6 = LD_SP(px); px += 4;
334                     ST_SP(x15, x); x += 4;
335                     x7 = LD_SP(px); px += 4;
336                 }
337
338                 LD_SP8_INC(px, 4, x8, x9, x10, x11, x12, x13, x14, x15);
339                 MUL4(x0, da_r_vec, x1, da_r_vec, x2, da_r_vec, x3, da_r_vec,
340                      x0, x1, x2, x3);
341                 MUL4(x4, da_r_vec, x5, da_r_vec, x6, da_r_vec, x7, da_r_vec,
342                      x4, x5, x6, x7);
343                 MUL4(x8, da_r_vec, x9, da_r_vec, x10, da_r_vec, x11, da_r_vec,
344                      x8, x9, x10, x11);
345                 MUL4(x12, da_r_vec, x13, da_r_vec, x14, da_r_vec, x15, da_r_vec,
346                      x12, x13, x14, x15);
347                 ST_SP16_INC(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11,
348                             x12, x13, x14, x15, x, 4);
349             }
350
351             if (n & 31)
352             {
353                 if (n & 16)
354                 {
355                     LD_SP8_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7);
356                     MUL4(x0, da_r_vec, x1, da_r_vec, x2, da_r_vec, x3, da_r_vec,
357                          x0, x1, x2, x3);
358                     MUL4(x4, da_r_vec, x5, da_r_vec, x6, da_r_vec, x7, da_r_vec,
359                          x4, x5, x6, x7);
360                     ST_SP8_INC(x0, x1, x2, x3, x4, x5, x6, x7, x, 4);
361                 }
362
363                 if (n & 8)
364                 {
365                     LD_SP4_INC(px, 4, x0, x1, x2, x3);
366                     MUL4(x0, da_r_vec, x1, da_r_vec, x2, da_r_vec, x3, da_r_vec,
367                          x0, x1, x2, x3);
368                     ST_SP4_INC(x0, x1, x2, x3, x, 4);
369                 }
370
371                 if (n & 4)
372                 {
373                     LD_SP2_INC(px, 4, x0, x1);
374                     MUL2(x0, da_r_vec, x1, da_r_vec, x0, x1);
375                     ST_SP2_INC(x0, x1, x, 4);
376                 }
377
378                 if (n & 2)
379                 {
380                     LD_GP4_INC(px, 1, f0, f1, f2, f3);
381                     MUL4(f0, da_r, f1, da_r, f2, da_r, f3, da_r, f0, f1, f2, f3);
382                     ST_GP4_INC(f0, f1, f2, f3, x, 1);
383                 }
384
385                 if (n & 1)
386                 {
387                     LD_GP2_INC(px, 1, f0, f1);
388                     MUL2(f0, da_r, f1, da_r, f0, f1);
389                     ST_GP2_INC(f0, f1, x, 1);
390                 }
391             }
392         }
393         else
394         {
395             FLOAT *x_pref;
396             BLASLONG pref_offset;
397
398             pref_offset = (BLASLONG)x & (L1_DATA_LINESIZE - 1);
399             if (pref_offset > 0)
400             {
401                 pref_offset = L1_DATA_LINESIZE - pref_offset;
402                 pref_offset = pref_offset / sizeof(FLOAT);
403             }
404             x_pref = x + pref_offset + 64;
405
406             da_i_vec = COPY_FLOAT_TO_VECTOR(da_i);
407             da_i_vec_neg = -da_i_vec;
408             da_i_vec = (v4f32) __msa_ilvev_w((v4i32) da_i_vec_neg, (v4i32) da_i_vec);
409
410             da_r_vec = COPY_FLOAT_TO_VECTOR(da_r);
411
412             for (i = (n >> 5); i--;)
413             {
414                 PREF_OFFSET(x_pref, 0);
415                 PREF_OFFSET(x_pref, 32);
416                 PREF_OFFSET(x_pref, 64);
417                 PREF_OFFSET(x_pref, 96);
418                 PREF_OFFSET(x_pref, 128);
419                 PREF_OFFSET(x_pref, 160);
420                 PREF_OFFSET(x_pref, 192);
421                 PREF_OFFSET(x_pref, 224);
422                 x_pref += 64;
423
424                 LD_SP16_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10,
425                             x11, x12, x13, x14, x15);
426                 MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
427                      d0, d1, d2, d3);
428                 MUL4(x4, da_i_vec, x5, da_i_vec, x6, da_i_vec, x7, da_i_vec,
429                      d4, d5, d6, d7);
430                 MUL4(x8, da_i_vec, x9, da_i_vec, x10, da_i_vec, x11, da_i_vec,
431                      d8, d9, d10, d11);
432                 MUL4(x12, da_i_vec, x13, da_i_vec, x14, da_i_vec, x15, da_i_vec,
433                      d12, d13, d14, d15);
434                 SHF_W4_SP(d0, d1, d2, d3, d0, d1, d2, d3, SHF_177);
435                 SHF_W4_SP(d4, d5, d6, d7, d4, d5, d6, d7, SHF_177);
436                 SHF_W4_SP(d8, d9, d10, d11, d8, d9, d10, d11, SHF_177);
437                 SHF_W4_SP(d12, d13, d14, d15, d12, d13, d14, d15, SHF_177);
438                 FMADD4(x0, x1, x2, x3, da_r_vec, d0, d1, d2, d3);
439                 FMADD4(x4, x5, x6, x7, da_r_vec, d4, d5, d6, d7);
440                 FMADD4(x8, x9, x10, x11, da_r_vec, d8, d9, d10, d11);
441                 FMADD4(x12, x13, x14, x15, da_r_vec, d12, d13, d14, d15);
442                 ST_SP16_INC(d0, d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11,
443                             d12, d13, d14, d15, x, 4);
444             }
445
446             if (n & 31)
447             {
448                 if (n & 16)
449                 {
450                     LD_SP8_INC(px, 4, x0, x1, x2, x3, x4, x5, x6, x7);
451                     MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
452                          d0, d1, d2, d3);
453                     MUL4(x4, da_i_vec, x5, da_i_vec, x6, da_i_vec, x7, da_i_vec,
454                          d4, d5, d6, d7);
455                     SHF_W4_SP(d0, d1, d2, d3, d0, d1, d2, d3, SHF_177);
456                     SHF_W4_SP(d4, d5, d6, d7, d4, d5, d6, d7, SHF_177);
457                     FMADD4(x0, x1, x2, x3, da_r_vec, d0, d1, d2, d3);
458                     FMADD4(x4, x5, x6, x7, da_r_vec, d4, d5, d6, d7);
459                     ST_SP8_INC(d0, d1, d2, d3, d4, d5, d6, d7, x, 4);
460                 }
461
462                 if (n & 8)
463                 {
464                     LD_SP4_INC(px, 4, x0, x1, x2, x3);
465                     MUL4(x0, da_i_vec, x1, da_i_vec, x2, da_i_vec, x3, da_i_vec,
466                          d0, d1, d2, d3);
467                     SHF_W4_SP(d0, d1, d2, d3, d0, d1, d2, d3, SHF_177);
468                     FMADD4(x0, x1, x2, x3, da_r_vec, d0, d1, d2, d3);
469                     ST_SP4_INC(d0, d1, d2, d3, x, 4);
470                 }
471
472                 if (n & 4)
473                 {
474                     LD_SP2_INC(px, 4, x0, x1);
475                     MUL2(x0, da_i_vec, x1, da_i_vec, d0, d1);
476                     SHF_W2_SP(d0, d1, d0, d1, SHF_177);
477                     FMADD2(x0, x1, da_r_vec, d0, d1);
478                     ST_SP2_INC(d0, d1, x, 4);
479                 }
480
481                 if (n & 2)
482                 {
483                     LD_GP4_INC(px, 1, f0, f1, f2, f3);
484
485                     tp0 = da_r * f0;
486                     tp0 -= da_i * f1;
487                     tp1 = da_r * f1;
488                     tp1 += da_i * f0;
489                     tp2 = da_r * f2;
490                     tp2 -= da_i * f3;
491                     tp3 = da_r * f3;
492                     tp3 += da_i * f2;
493
494                     ST_GP4_INC(tp0, tp1, tp2, tp3, x, 1);
495                 }
496
497                 if (n & 1)
498                 {
499                     LD_GP2_INC(px, 1, f0, f1);
500
501                     tp0 = da_r * f0;
502                     tp0 -= da_i * f1;
503                     tp1 = da_r * f1;
504                     tp1 += da_i * f0;
505
506                     ST_GP2_INC(tp0, tp1, x, 1);
507                 }
508             }
509         }
510     }
511     else
512     {
513         inc_x2 = 2 * inc_x;
514
515         if ((0.0 == da_r) && (0.0 == da_i))
516         {
517             for (i = n; i--;)
518             {
519                 *x       = 0;
520                 *(x + 1) = 0;
521
522                 x += inc_x2;
523             }
524         }
525         else if (0.0 == da_r)
526         {
527             da_i_vec = COPY_FLOAT_TO_VECTOR(da_i);
528             da_i_vec_neg = -da_i_vec;
529             da_i_vec = (v4f32) __msa_ilvev_w((v4i32) da_i_vec_neg, (v4i32) da_i_vec);
530
531             for (i = (n >> 4); i--;)
532             {
533                 LD_SP16_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9,
534                             x10, x11, x12, x13, x14, x15);
535                 PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
536                 PCKEV_D4_SP(x9, x8, x11, x10, x13, x12, x15, x14, d4, d5, d6, d7);
537                 MUL4(d0, da_i_vec, d1, da_i_vec, d2, da_i_vec, d3, da_i_vec,
538                      d0, d1, d2, d3);
539                 MUL4(d4, da_i_vec, d5, da_i_vec, d6, da_i_vec, d7, da_i_vec,
540                      d4, d5, d6, d7);
541
542                 *x       = d0[1];
543                 *(x + 1) = d0[0];
544                 x += inc_x2;
545                 *x       = d0[3];
546                 *(x + 1) = d0[2];
547                 x += inc_x2;
548                 *x       = d1[1];
549                 *(x + 1) = d1[0];
550                 x += inc_x2;
551                 *x       = d1[3];
552                 *(x + 1) = d1[2];
553                 x += inc_x2;
554                 *x       = d2[1];
555                 *(x + 1) = d2[0];
556                 x += inc_x2;
557                 *x       = d2[3];
558                 *(x + 1) = d2[2];
559                 x += inc_x2;
560                 *x       = d3[1];
561                 *(x + 1) = d3[0];
562                 x += inc_x2;
563                 *x       = d3[3];
564                 *(x + 1) = d3[2];
565                 x += inc_x2;
566                 *x       = d4[1];
567                 *(x + 1) = d4[0];
568                 x += inc_x2;
569                 *x       = d4[3];
570                 *(x + 1) = d4[2];
571                 x += inc_x2;
572                 *x       = d5[1];
573                 *(x + 1) = d5[0];
574                 x += inc_x2;
575                 *x       = d5[3];
576                 *(x + 1) = d5[2];
577                 x += inc_x2;
578                 *x       = d6[1];
579                 *(x + 1) = d6[0];
580                 x += inc_x2;
581                 *x       = d6[3];
582                 *(x + 1) = d6[2];
583                 x += inc_x2;
584                 *x       = d7[1];
585                 *(x + 1) = d7[0];
586                 x += inc_x2;
587                 *x       = d7[3];
588                 *(x + 1) = d7[2];
589                 x += inc_x2;
590             }
591
592             if (n & 15)
593             {
594                 if (n & 8)
595                 {
596                     LD_SP8_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7);
597                     PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
598                     MUL4(d0, da_i_vec, d1, da_i_vec, d2, da_i_vec, d3, da_i_vec,
599                          d0, d1, d2, d3);
600
601                     *x       = d0[1];
602                     *(x + 1) = d0[0];
603                     x += inc_x2;
604                     *x       = d0[3];
605                     *(x + 1) = d0[2];
606                     x += inc_x2;
607                     *x       = d1[1];
608                     *(x + 1) = d1[0];
609                     x += inc_x2;
610                     *x       = d1[3];
611                     *(x + 1) = d1[2];
612                     x += inc_x2;
613                     *x       = d2[1];
614                     *(x + 1) = d2[0];
615                     x += inc_x2;
616                     *x       = d2[3];
617                     *(x + 1) = d2[2];
618                     x += inc_x2;
619                     *x       = d3[1];
620                     *(x + 1) = d3[0];
621                     x += inc_x2;
622                     *x       = d3[3];
623                     *(x + 1) = d3[2];
624                     x += inc_x2;
625                 }
626
627                 if (n & 4)
628                 {
629                     LD_SP4_INC(px, inc_x2, x0, x1, x2, x3);
630                     PCKEV_D2_SP(x1, x0, x3, x2, d0, d1);
631                     MUL2(d0, da_i_vec, d1, da_i_vec, d0, d1);
632
633                     *x       = d0[1];
634                     *(x + 1) = d0[0];
635                     x += inc_x2;
636                     *x       = d0[3];
637                     *(x + 1) = d0[2];
638                     x += inc_x2;
639                     *x       = d1[1];
640                     *(x + 1) = d1[0];
641                     x += inc_x2;
642                     *x       = d1[3];
643                     *(x + 1) = d1[2];
644                     x += inc_x2;
645                 }
646
647                 if (n & 2)
648                 {
649                     f0 = *px;
650                     f1 = *(px + 1);
651                     px += inc_x2;
652                     f2 = *px;
653                     f3 = *(px + 1);
654                     px += inc_x2;
655
656                     MUL4(f0, da_i, f1, -da_i, f2, da_i, f3, -da_i, f0, f1, f2, f3);
657
658                     *x       = f1;
659                     *(x + 1) = f0;
660                     x += inc_x2;
661                     *x       = f3;
662                     *(x + 1) = f2;
663                     x += inc_x2;
664                 }
665
666                 if (n & 1)
667                 {
668                     f0 = *x;
669                     f1 = *(x + 1);
670
671                     MUL2(f0, da_i, f1, -da_i, f0, f1);
672
673                     *x       = f1;
674                     *(x + 1) = f0;
675                 }
676             }
677         }
678         else if (0.0 == da_i)
679         {
680             da_r_vec = COPY_FLOAT_TO_VECTOR(da_r);
681
682             for (i = (n >> 4); i--;)
683             {
684                 LD_SP16_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9,
685                             x10, x11, x12, x13, x14, x15);
686                 PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
687                 PCKEV_D4_SP(x9, x8, x11, x10, x13, x12, x15, x14, d4, d5, d6, d7);
688                 MUL4(d0, da_r_vec, d1, da_r_vec, d2, da_r_vec, d3, da_r_vec,
689                      d0, d1, d2, d3);
690                 MUL4(d4, da_r_vec, d5, da_r_vec, d6, da_r_vec, d7, da_r_vec,
691                      d4, d5, d6, d7);
692
693                 *x       = d0[0];
694                 *(x + 1) = d0[1];
695                 x += inc_x2;
696                 *x       = d0[2];
697                 *(x + 1) = d0[3];
698                 x += inc_x2;
699                 *x       = d1[0];
700                 *(x + 1) = d1[1];
701                 x += inc_x2;
702                 *x       = d1[2];
703                 *(x + 1) = d1[3];
704                 x += inc_x2;
705                 *x       = d2[0];
706                 *(x + 1) = d2[1];
707                 x += inc_x2;
708                 *x       = d2[2];
709                 *(x + 1) = d2[3];
710                 x += inc_x2;
711                 *x       = d3[0];
712                 *(x + 1) = d3[1];
713                 x += inc_x2;
714                 *x       = d3[2];
715                 *(x + 1) = d3[3];
716                 x += inc_x2;
717                 *x       = d4[0];
718                 *(x + 1) = d4[1];
719                 x += inc_x2;
720                 *x       = d4[2];
721                 *(x + 1) = d4[3];
722                 x += inc_x2;
723                 *x       = d5[0];
724                 *(x + 1) = d5[1];
725                 x += inc_x2;
726                 *x       = d5[2];
727                 *(x + 1) = d5[3];
728                 x += inc_x2;
729                 *x       = d6[0];
730                 *(x + 1) = d6[1];
731                 x += inc_x2;
732                 *x       = d6[2];
733                 *(x + 1) = d6[3];
734                 x += inc_x2;
735                 *x       = d7[0];
736                 *(x + 1) = d7[1];
737                 x += inc_x2;
738                 *x       = d7[2];
739                 *(x + 1) = d7[3];
740                 x += inc_x2;
741             }
742
743             if (n & 15)
744             {
745                 if (n & 8)
746                 {
747                     LD_SP8_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7);
748                     PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
749                     MUL4(d0, da_r_vec, d1, da_r_vec, d2, da_r_vec, d3, da_r_vec,
750                          d0, d1, d2, d3);
751
752                     *x       = d0[0];
753                     *(x + 1) = d0[1];
754                     x += inc_x2;
755                     *x       = d0[2];
756                     *(x + 1) = d0[3];
757                     x += inc_x2;
758                     *x       = d1[0];
759                     *(x + 1) = d1[1];
760                     x += inc_x2;
761                     *x       = d1[2];
762                     *(x + 1) = d1[3];
763                     x += inc_x2;
764                     *x       = d2[0];
765                     *(x + 1) = d2[1];
766                     x += inc_x2;
767                     *x       = d2[2];
768                     *(x + 1) = d2[3];
769                     x += inc_x2;
770                     *x       = d3[0];
771                     *(x + 1) = d3[1];
772                     x += inc_x2;
773                     *x       = d3[2];
774                     *(x + 1) = d3[3];
775                     x += inc_x2;
776                 }
777
778                 if (n & 4)
779                 {
780                     LD_SP4_INC(px, inc_x2, x0, x1, x2, x3);
781                     PCKEV_D2_SP(x1, x0, x3, x2, d0, d1);
782                     MUL2(d0, da_r_vec, d1, da_r_vec, d0, d1);
783
784                     *x       = d0[0];
785                     *(x + 1) = d0[1];
786                     x += inc_x2;
787                     *x       = d0[2];
788                     *(x + 1) = d0[3];
789                     x += inc_x2;
790                     *x       = d1[0];
791                     *(x + 1) = d1[1];
792                     x += inc_x2;
793                     *x       = d1[2];
794                     *(x + 1) = d1[3];
795                     x += inc_x2;
796                 }
797
798                 if (n & 2)
799                 {
800                     f0 = *px;
801                     f1 = *(px + 1);
802                     px += inc_x2;
803                     f2 = *px;
804                     f3 = *(px + 1);
805                     px += inc_x2;
806
807                     MUL4(f0, da_r, f1, da_r, f2, da_r, f3, da_r, f0, f1, f2, f3);
808
809                     *x       = f0;
810                     *(x + 1) = f1;
811                     x += inc_x2;
812                     *x       = f2;
813                     *(x + 1) = f3;
814                     x += inc_x2;
815                 }
816
817                 if (n & 1)
818                 {
819                     f0 = *x;
820                     f1 = *(x + 1);
821
822                     MUL2(f0, da_r, f1, da_r, f0, f1);
823
824                     *x       = f0;
825                     *(x + 1) = f1;
826                 }
827             }
828         }
829         else
830         {
831             da_i_vec = COPY_FLOAT_TO_VECTOR(da_i);
832             da_i_vec_neg = -da_i_vec;
833             da_i_vec = (v4f32) __msa_ilvev_w((v4i32) da_i_vec_neg, (v4i32) da_i_vec);
834
835             da_r_vec = COPY_FLOAT_TO_VECTOR(da_r);
836
837             for (i = (n >> 4); i--;)
838             {
839                 LD_SP16_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9,
840                             x10, x11, x12, x13, x14, x15);
841                 PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
842                 PCKEV_D4_SP(x9, x8, x11, x10, x13, x12, x15, x14, d4, d5, d6, d7);
843                 MUL4(d0, da_i_vec, d1, da_i_vec, d2, da_i_vec, d3, da_i_vec,
844                      x0, x1, x2, x3);
845                 MUL4(d4, da_i_vec, d5, da_i_vec, d6, da_i_vec, d7, da_i_vec,
846                      x4, x5, x6, x7);
847                 MUL4(d0, da_r_vec, d1, da_r_vec, d2, da_r_vec, d3, da_r_vec,
848                      d0, d1, d2, d3);
849                 MUL4(d4, da_r_vec, d5, da_r_vec, d6, da_r_vec, d7, da_r_vec,
850                      d4, d5, d6, d7);
851                 SHF_W4_SP(x0, x1, x2, x3, x0, x1, x2, x3, SHF_177);
852                 SHF_W4_SP(x4, x5, x6, x7, x4, x5, x6, x7, SHF_177);
853                 ADD4(d0, x0, d1, x1, d2, x2, d3, x3, d0, d1, d2, d3);
854                 ADD4(d4, x4, d5, x5, d6, x6, d7, x7, d4, d5, d6, d7);
855
856                 *x       = d0[0];
857                 *(x + 1) = d0[1];
858                 x += inc_x2;
859                 *x       = d0[2];
860                 *(x + 1) = d0[3];
861                 x += inc_x2;
862                 *x       = d1[0];
863                 *(x + 1) = d1[1];
864                 x += inc_x2;
865                 *x       = d1[2];
866                 *(x + 1) = d1[3];
867                 x += inc_x2;
868                 *x       = d2[0];
869                 *(x + 1) = d2[1];
870                 x += inc_x2;
871                 *x       = d2[2];
872                 *(x + 1) = d2[3];
873                 x += inc_x2;
874                 *x       = d3[0];
875                 *(x + 1) = d3[1];
876                 x += inc_x2;
877                 *x       = d3[2];
878                 *(x + 1) = d3[3];
879                 x += inc_x2;
880                 *x       = d4[0];
881                 *(x + 1) = d4[1];
882                 x += inc_x2;
883                 *x       = d4[2];
884                 *(x + 1) = d4[3];
885                 x += inc_x2;
886                 *x       = d5[0];
887                 *(x + 1) = d5[1];
888                 x += inc_x2;
889                 *x       = d5[2];
890                 *(x + 1) = d5[3];
891                 x += inc_x2;
892                 *x       = d6[0];
893                 *(x + 1) = d6[1];
894                 x += inc_x2;
895                 *x       = d6[2];
896                 *(x + 1) = d6[3];
897                 x += inc_x2;
898                 *x       = d7[0];
899                 *(x + 1) = d7[1];
900                 x += inc_x2;
901                 *x       = d7[2];
902                 *(x + 1) = d7[3];
903                 x += inc_x2;
904             }
905
906             if (n & 15)
907             {
908                 if (n & 8)
909                 {
910                     LD_SP8_INC(px, inc_x2, x0, x1, x2, x3, x4, x5, x6, x7);
911                     PCKEV_D4_SP(x1, x0, x3, x2, x5, x4, x7, x6, d0, d1, d2, d3);
912                     MUL4(d0, da_i_vec, d1, da_i_vec, d2, da_i_vec, d3, da_i_vec,
913                          x0, x1, x2, x3);
914                     MUL4(d0, da_r_vec, d1, da_r_vec, d2, da_r_vec, d3, da_r_vec,
915                          d0, d1, d2, d3);
916                     SHF_W4_SP(x0, x1, x2, x3, x0, x1, x2, x3, SHF_177);
917                     ADD4(d0, x0, d1, x1, d2, x2, d3, x3, d0, d1, d2, d3);
918
919                     *x       = d0[0];
920                     *(x + 1) = d0[1];
921                     x += inc_x2;
922                     *x       = d0[2];
923                     *(x + 1) = d0[3];
924                     x += inc_x2;
925                     *x       = d1[0];
926                     *(x + 1) = d1[1];
927                     x += inc_x2;
928                     *x       = d1[2];
929                     *(x + 1) = d1[3];
930                     x += inc_x2;
931                     *x       = d2[0];
932                     *(x + 1) = d2[1];
933                     x += inc_x2;
934                     *x       = d2[2];
935                     *(x + 1) = d2[3];
936                     x += inc_x2;
937                     *x       = d3[0];
938                     *(x + 1) = d3[1];
939                     x += inc_x2;
940                     *x       = d3[2];
941                     *(x + 1) = d3[3];
942                     x += inc_x2;
943                 }
944
945                 if (n & 4)
946                 {
947                     LD_SP4_INC(px, inc_x2, x0, x1, x2, x3);
948                     PCKEV_D2_SP(x1, x0, x3, x2, d0, d1);
949                     MUL2(d0, da_i_vec, d1, da_i_vec, x0, x1);
950                     MUL2(d0, da_r_vec, d1, da_r_vec, d0, d1);
951                     SHF_W2_SP(x0, x1, x0, x1, SHF_177);
952                     ADD2(d0, x0, d1, x1, d0, d1);
953
954                     *x       = d0[0];
955                     *(x + 1) = d0[1];
956                     x += inc_x2;
957                     *x       = d0[2];
958                     *(x + 1) = d0[3];
959                     x += inc_x2;
960                     *x       = d1[0];
961                     *(x + 1) = d1[1];
962                     x += inc_x2;
963                     *x       = d1[2];
964                     *(x + 1) = d1[3];
965                     x += inc_x2;
966                 }
967
968                 if (n & 2)
969                 {
970                     f0 = *px;;
971                     f1 = *(px + 1);
972                     px += inc_x2;
973                     f2 = *px;
974                     f3 = *(px + 1);
975                     px += inc_x2;
976
977                     tp0 = da_r * f0;
978                     tp0 -= da_i * f1;
979                     tp1 = da_r * f1;
980                     tp1 += da_i * f0;
981                     tp2 = da_r * f2;
982                     tp2 -= da_i * f3;
983                     tp3 = da_r * f3;
984                     tp3 += da_i * f2;
985
986                     *x       = tp0;
987                     *(x + 1) = tp1;
988                     x += inc_x2;
989                     *x       = tp2;
990                     *(x + 1) = tp3;
991                     x += inc_x2;
992                 }
993
994                 if (n & 1)
995                 {
996                     f0 = *px; px += 1;
997                     f1 = *px;
998
999                     tp0 = da_r * f0;
1000                     tp0 -= da_i * f1;
1001                     tp1 = da_r * f1;
1002                     tp1 += da_i * f0;
1003
1004                     *x = tp0; x += 1;
1005                     *x = tp1;
1006                 }
1007             }
1008         }
1009     }
1010
1011     return (0);
1012 }