1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/*
19
20 Pathname: fxp_mul32_arm_v4_gcc.h
21
22------------------------------------------------------------------------------
23 REVISION HISTORY
24
25 Who:                                       Date:
26 Description:
27------------------------------------------------------------------------------
28 INCLUDE DESCRIPTION
29
30------------------------------------------------------------------------------
31*/
32
33
34
35#ifndef FXP_MUL32_V4_ARM_GCC
36#define FXP_MUL32_V4_ARM_GCC
37
38
39#ifdef __cplusplus
40extern "C"
41{
42#endif
43
44
45#include "pv_audio_type_defs.h"
46
47
48#if defined (_ARM_V4_GCC) /* ARM_V4 GNU COMPILER  */
49
50
51#define preload_cache( a)
52
53
54    static inline  Int32 shft_lft_1(Int32 L_var1)
55    {
56        Int32 x;
57        register Int32 ra = L_var1;
58        Int32 z = INT32_MAX;
59
60        asm volatile(
61            "mov %0, %1, asl #1\n\t"
62            "teq %1, %0, asr #1\n\t"
63            "eorne   %0, %2, %1, asr #31"
64    : "=&r*i"(x)
65                    : "r"(ra),
66                    "r"(z));
67
68        return(x);
69    }
70
71    static inline Int32 fxp_mul_16_by_16bb(Int32 L_var1, Int32 L_var2)
72{
73
74        Int32 tmp1;
75        Int32 tmp2;
76        register Int32 ra = (Int32)L_var1;
77        register Int32 rb = (Int32)L_var2;
78
79        asm volatile(
80            "mov %0, %3, asl #16\n\t"
81            "mov %0, %0, asr #16\n\t"
82            "mov %1, %2, asl #16\n\t"
83            "mov %1, %1, asr #16\n\t"
84            "mul %0, %1, %0"
85    : "=&r*i"(tmp1),
86            "=&r*i"(tmp2)
87                    : "r"(ra),
88                    "r"(rb));
89
90        return (tmp1);
91
92    }
93
94#define fxp_mul_16_by_16(a, b)  fxp_mul_16_by_16bb(  a, b)
95
96
97    static inline Int32 fxp_mul_16_by_16tb(Int32 L_var1, Int32 L_var2)
98{
99
100        Int32 tmp1;
101        Int32 tmp2;
102        register Int32 ra = (Int32)L_var1;
103        register Int32 rb = (Int32)L_var2;
104
105        asm volatile(
106            "mov %0, %3, asl #16\n\t"
107            "mov %0, %0, asr #16\n\t"
108            "mov %1, %2, asr #16\n\t"
109            "mul %0, %1, %0"
110    : "=&r*i"(tmp1),
111            "=&r*i"(tmp2)
112                    : "r"(ra),
113                    "r"(rb));
114
115        return (tmp1);
116
117    }
118
119
120    static inline Int32 fxp_mul_16_by_16bt(Int32 L_var1, Int32 L_var2)
121{
122
123        Int32 tmp1;
124        Int32 tmp2;
125        register Int32 ra = (Int32)L_var1;
126        register Int32 rb = (Int32)L_var2;
127
128        asm volatile(
129            "mov %0, %3, asr #16\n\t"
130            "mov %1, %2, asl #16\n\t"
131            "mov %1, %1, asr #16\n\t"
132            "mul %0, %1, %0"
133    : "=&r*i"(tmp1),
134            "=&r*i"(tmp2)
135                    : "r"(ra),
136                    "r"(rb));
137
138        return (tmp1);
139
140    }
141
142
143    static inline Int32 fxp_mul_16_by_16tt(Int32 L_var1, Int32 L_var2)
144{
145
146        Int32 tmp1;
147        Int32 tmp2;
148        register Int32 ra = (Int32)L_var1;
149        register Int32 rb = (Int32)L_var2;
150
151        asm volatile(
152            "mov %0, %3, asr #16\n\t"
153            "mov %1, %2, asr #16\n\t"
154            "mul %0, %1, %0"
155    : "=&r*i"(tmp1),
156            "=&r*i"(tmp2)
157                    : "r"(ra),
158                    "r"(rb));
159
160        return (tmp1);
161
162    }
163
164
165
166    static inline  Int32 fxp_mac_16_by_16(Int16 L_var1,  Int16 L_var2, Int32 L_add)
167{
168
169        Int32 tmp;
170        register Int32 ra = (Int32)L_var1;
171        register Int32 rb = (Int32)L_var2;
172        register Int32 rc = (Int32)L_add;
173
174        asm volatile(
175            "mla %0, %1, %2, %3"
176    : "=&r*i"(tmp)
177                    : "r"(ra),
178                    "r"(rb),
179                    "r"(rc));
180
181        return (tmp);
182    }
183
184
185
186    static inline Int32 fxp_mac_16_by_16_bb(Int16 L_var1,  Int32 L_var2, Int32 L_add)
187{
188
189        Int32 tmp1;
190        Int32 tmp2;
191        register Int32 ra = (Int32)L_var1;
192        register Int32 rb = (Int32)L_var2;
193        register Int32 rc = (Int32)L_add;
194
195        asm volatile(
196            "mov %0, %3, asl #16\n\t"
197            "mov %0, %0, asr #16\n\t"
198            "mla %1, %0, %2, %4"
199    : "=&r*i"(tmp1),
200            "=&r*i"(tmp2)
201                    : "r"(ra),
202                    "r"(rb),
203                    "r"(rc));
204
205        return (tmp2);
206    }
207
208
209
210    static inline  Int32 fxp_mac_16_by_16_bt(Int16 L_var1,  Int32 L_var2, Int32 L_add)
211{
212
213        Int32 tmp1;
214        Int32 tmp2;
215        register Int32 ra = (Int32)L_var1;
216        register Int32 rb = (Int32)L_var2;
217        register Int32 rc = (Int32)L_add;
218
219        asm volatile(
220            "mov %0, %3, asr #16\n\t"
221            "mla %1, %0, %2, %4"
222    : "=&r*i"(tmp1),
223            "=&r*i"(tmp2)
224                    : "r"(ra),
225                    "r"(rb),
226                    "r"(rc));
227
228        return (tmp2);
229
230    }
231
232
233
234    static inline  Int32 cmplx_mul32_by_16(Int32 x, Int32 y, Int32 exp_jw)
235{
236
237        Int32 rTmp0;
238        Int32 iTmp0;
239        Int32 result64_hi;
240        register Int32 ra = (Int32)x;
241        register Int32 rb = (Int32)y;
242        register Int32 rc = (Int32)exp_jw;
243
244
245
246        asm volatile(
247            "mov %0, %5, asr #16\n\t"
248            "mov %1, %5, asl #16\n\t"
249            "mov %0, %0, asl #16\n\t"
250    : "=&r*i"(rTmp0),
251            "=&r*i"(iTmp0),
252            "=&r*i"(result64_hi)
253                    : "r"(ra),
254                    "r"(rb),
255                    "r"(rc));
256
257
258        asm volatile(
259            "smull %0, %2, %3, %0\n\t"
260            "smlal %1, %2, %4, %1"
261    : "=&r*i"(rTmp0),
262            "=&r*i"(iTmp0),
263            "=&r*i"(result64_hi)
264                    : "r"(ra),
265                    "r"(rb),
266                    "r"(rc));
267
268        return (result64_hi);
269
270
271    }
272
273
274    static inline  Int32 fxp_mul32_by_16(Int32 L_var1, Int32 L_var2)
275{
276
277        Int32 rTmp0;
278        Int32 result64_hi;
279        Int32 result64_lo;
280        register Int32 ra = (Int32)L_var1;
281        register Int32 rb = (Int32)L_var2;
282
283        asm volatile(
284            "mov %0, %4, asl #16\n\t"
285            "smull %2, %1, %0, %3"
286    : "=&r*i"(rTmp0),
287            "=&r*i"(result64_hi),
288            "=&r*i"(result64_lo)
289                    : "r"(ra),
290                    "r"(rb));
291
292        return (result64_hi);
293    }
294
295
296#define fxp_mul32_by_16b( a, b)   fxp_mul32_by_16( a, b)
297
298
299
300    static inline  Int32 fxp_mul32_by_16t(Int32 L_var1, Int32 L_var2)
301{
302
303        Int32 rTmp0;
304        Int32 result64_hi;
305        Int32 result64_lo;
306        register Int32 ra = (Int32)L_var1;
307        register Int32 rb = (Int32)L_var2;
308
309        asm volatile(
310            "mov %0, %4, asr #16\n\t"
311            "mov %0, %0, asl #16\n\t"
312            "smull %2, %1, %0, %3"
313    : "=&r*i"(rTmp0),
314            "=&r*i"(result64_hi),
315            "=&r*i"(result64_lo)
316                    : "r"(ra),
317                    "r"(rb));
318
319        return (result64_hi);
320    }
321
322
323
324    static inline  Int32 fxp_mac32_by_16(Int32 L_var1, Int32 L_var2, Int32 L_add)
325{
326
327        Int32 rTmp0;
328        Int32 result64_hi;
329        Int32 result64_lo;
330        register Int32 ra = (Int32)L_var1;
331        register Int32 rb = (Int32)L_var2;
332        register Int32 rc = (Int32)L_add;
333
334        asm volatile(
335            "mov %0, %4, asl #16\n\t"
336            "mov %1, %5\n\t"
337            "smlal %2, %1, %0, %3"
338    : "=&r*i"(rTmp0),
339            "=&r*i"(result64_hi),
340            "=&r*i"(result64_lo)
341                    : "r"(ra),
342                    "r"(rb),
343                    "r"(rc));
344
345        return (result64_hi);
346    }
347
348
349    static inline int64 fxp_mac64_Q31(int64 sum, const Int32 L_var1, const Int32 L_var2)
350{
351        sum += (int64)L_var1 * L_var2;
352        return (sum);
353    }
354
355
356    static inline Int32 fxp_mac32_Q30(const Int32 a, const Int32 b, Int32 L_add)
357    {
358        Int32 result64_hi;
359        Int32 result64_lo;
360        register Int32 ra = (Int32)a;
361        register Int32 rb = (Int32)b;
362        register Int32 rc = (Int32)L_add;
363
364        asm volatile("smull %1, %0, %2, %3\n\t"
365                     "add %4, %4, %0, asl #2\n\t"
366                     "add %0, %4, %1, lsr #30"
367             : "=&r*i"(result64_hi),
368                     "=&r*i"(result64_lo)
369                             : "r"(ra),
370                             "r"(rb),
371                             "r"(rc));
372
373        return (result64_hi);
374    }
375
376
377    static inline Int32 fxp_mac32_Q31(Int32 L_add, const Int32 a, const Int32 b)
378{
379
380        Int32 result64_hi;
381        Int32 result64_lo;
382        register Int32 ra = (Int32)a;
383        register Int32 rb = (Int32)b;
384        register Int32 rc = (Int32)L_add;
385
386        asm volatile("smull %1, %0, %2, %3\n\t"
387                     "add %0, %0, %4"
388             : "=&r*i"(result64_hi),
389                     "=&r*i"(result64_lo)
390                             : "r"(ra),
391                             "r"(rb),
392                             "r"(rc));
393
394        return (result64_hi);
395    }
396
397
398
399    static inline Int32 fxp_msu32_Q31(Int32 L_sub, const Int32 a, const Int32 b)
400{
401        Int32 result64_hi;
402        Int32 result64_lo;
403        register Int32 ra = (Int32)a;
404        register Int32 rb = (Int32)b;
405        register Int32 rc = (Int32)L_sub;
406
407        asm volatile("smull %1, %0, %2, %3\n\t"
408                     "sub %0, %4, %0"
409             : "=&r*i"(result64_hi),
410                     "=&r*i"(result64_lo)
411                             : "r"(ra),
412                             "r"(rb),
413                             "r"(rc));
414
415
416        return (result64_hi);
417    }
418
419
420    static inline Int32 fxp_mul32_Q31(const Int32 a, const Int32 b)
421{
422        Int32 result64_hi;
423        Int32 result64_lo;
424        register Int32 ra = (Int32)a;
425        register Int32 rb = (Int32)b;
426        asm volatile(
427            "smull %1, %0, %2, %3"
428    : "=&r*i"(result64_hi),
429            "=&r*i"(result64_lo)
430                    : "r"(ra),
431                    "r"(rb));
432
433        return (result64_hi);
434    }
435
436
437    static inline Int32 fxp_mul32_Q30(const Int32 a, const Int32 b)
438{
439        Int32 result64_hi;
440        Int32 result64_lo;
441        register Int32 ra = (Int32)a;
442        register Int32 rb = (Int32)b;
443        asm volatile("smull %1, %0, %2, %3\n\t"
444                     "mov %0, %0, lsl #2\n\t"
445                     "orr   %0, %0, %1, lsr #30"
446             : "=&r*i"(result64_hi),
447                     "=&r*i"(result64_lo)
448                             : "r"(ra),
449                             "r"(rb));
450        return (result64_hi);
451    }
452
453
454
455    static inline Int32 fxp_mac32_Q29(const Int32 a, const Int32 b, Int32 L_add)
456{
457        Int32 result64_hi;
458        Int32 result64_lo;
459        register Int32 ra = (Int32)a;
460        register Int32 rb = (Int32)b;
461        register Int32 rc = (Int32)L_add;
462
463        asm volatile("smull %1, %0, %2, %3\n\t"
464                     "add   %4, %4, %0, lsl #3\n\t"
465                     "add   %0, %4, %1, lsr #29"
466             : "=&r*i"(result64_hi),
467                     "=&r*i"(result64_lo)
468                             : "r"(ra),
469                             "r"(rb),
470                             "r"(rc));
471
472        return (result64_hi);
473    }
474
475
476    static inline Int32 fxp_msu32_Q29(const Int32 a, const Int32 b, Int32 L_sub)
477{
478        Int32 result64_hi;
479        Int32 result64_lo;
480        register Int32 ra = (Int32)a;
481        register Int32 rb = (Int32)b;
482        register Int32 rc = (Int32)L_sub;
483
484        asm volatile("smull %1, %0, %2, %3\n\t"
485                     "sub   %4, %4, %0, lsl #3\n\t"
486                     "sub   %0, %4, %1, lsr #29"
487             : "=&r*i"(result64_hi),
488                     "=&r*i"(result64_lo)
489                             : "r"(ra),
490                             "r"(rb),
491                             "r"(rc));
492
493        return (result64_hi);
494    }
495
496    static inline Int32 fxp_mul32_Q29(const Int32 a, const Int32 b)
497{
498        Int32 result64_hi;
499        Int32 result64_lo;
500        register Int32 ra = (Int32)a;
501        register Int32 rb = (Int32)b;
502        asm volatile("smull %1, %0, %2, %3\n\t"
503                     "mov %0, %0, lsl #3\n\t"
504                     "orr   %0, %0, %1, lsr #29"
505             : "=&r*i"(result64_hi),
506                     "=&r*i"(result64_lo)
507                             : "r"(ra),
508                             "r"(rb));
509        return (result64_hi);
510    }
511
512
513
514    static inline Int32 fxp_mul32_Q28(const Int32 a, const Int32 b)
515{
516        Int32 result64_hi;
517        Int32 result64_lo;
518        register Int32 ra = (Int32)a;
519        register Int32 rb = (Int32)b;
520        asm volatile("smull %1, %0, %2, %3\n\t"
521                     "mov %0, %0, lsl #4\n\t"
522                     "orr   %0, %0, %1, lsr #28"
523             : "=&r*i"(result64_hi),
524                     "=&r*i"(result64_lo)
525                             : "r"(ra),
526                             "r"(rb));
527        return (result64_hi);
528    }
529
530    static inline Int32 fxp_mul32_Q27(const Int32 a, const Int32 b)
531{
532        Int32 result64_hi;
533        Int32 result64_lo;
534        register Int32 ra = (Int32)a;
535        register Int32 rb = (Int32)b;
536        asm volatile("smull %1, %0, %2, %3\n\t"
537                     "mov %0, %0, lsl #5\n\t"
538                     "orr   %0, %0, %1, lsr #27"
539             : "=&r*i"(result64_hi),
540                     "=&r*i"(result64_lo)
541                             : "r"(ra),
542                             "r"(rb));
543
544        return (result64_hi);
545    }
546
547
548    static inline Int32 fxp_mul32_Q26(const Int32 a, const Int32 b)
549{
550        Int32 result64_hi;
551        Int32 result64_lo;
552        register Int32 ra = (Int32)a;
553        register Int32 rb = (Int32)b;
554        asm volatile("smull %1, %0, %2, %3\n\t"
555                     "mov %0, %0, lsl #6\n\t"
556                     "orr   %0, %0, %1, lsr #26"
557             : "=&r*i"(result64_hi),
558                     "=&r*i"(result64_lo)
559                             : "r"(ra),
560                             "r"(rb));
561
562        return (result64_hi);
563    }
564
565
566    static inline Int32 fxp_mul32_Q20(const Int32 a, const Int32 b)
567{
568        Int32 result64_hi;
569        Int32 result64_lo;
570        register Int32 ra = (Int32)a;
571        register Int32 rb = (Int32)b;
572        asm volatile("smull %1, %0, %2, %3\n\t"
573                     "mov %0, %0, lsl #12\n\t"
574                     "orr   %0, %0, %1, lsr #20"
575             : "=&r*i"(result64_hi),
576                     "=&r*i"(result64_lo)
577                             : "r"(ra),
578                             "r"(rb));
579
580        return (result64_hi);
581    }
582
583
584    static inline Int32 fxp_mul32_Q15(const Int32 a, const Int32 b)
585{
586        Int32 result64_hi;
587        Int32 result64_lo;
588        register Int32 ra = (Int32)a;
589        register Int32 rb = (Int32)b;
590        asm volatile("smull %1, %0, %2, %3\n\t"
591                     "mov %0, %0, lsl #17\n\t"
592                     "orr   %0, %0, %1, lsr #15"
593             : "=&r*i"(result64_hi),
594                     "=&r*i"(result64_lo)
595                             : "r"(ra),
596                             "r"(rb));
597
598        return (result64_hi);
599    }
600
601
602
603    static inline Int32 fxp_mul32_Q14(const Int32 a, const Int32 b)
604{
605        Int32 result64_hi;
606        Int32 result64_lo;
607        register Int32 ra = (Int32)a;
608        register Int32 rb = (Int32)b;
609        asm volatile("smull %1, %0, %2,  %3\n\t"
610                     "mov   %0, %0, lsl #18\n\t"
611                     "orr   %0, %0, %1, lsr #14"
612             : "=&r*i"(result64_hi),
613                     "=&r*i"(result64_lo)
614                             : "r"(ra),
615                             "r"(rb));
616
617        return (result64_hi);
618    }
619
620#endif
621
622#ifdef __cplusplus
623}
624#endif
625
626
627#endif   /*  FXP_MUL32_V4_ARM_GCC  */
628
629
630
631