LCOV - code coverage report
Current view: top level - lib_com - ifft_rel_fx.c (source / functions) Hit Total Coverage
Test: Coverage on main -- dec/rend @ 633e3f2e309758d10805ef21e0436356fe719b7a Lines: 305 331 92.1 %
Date: 2025-08-23 01:22:27 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /******************************************************************************************************
       2             : 
       3             :    (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
       4             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
       5             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
       6             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
       7             :    contributors to this repository. All Rights Reserved.
       8             : 
       9             :    This software is protected by copyright law and by international treaties.
      10             :    The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
      11             :    Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
      12             :    Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
      13             :    Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
      14             :    contributors to this repository retain full ownership rights in their respective contributions in
      15             :    the software. This notice grants no license of any kind, including but not limited to patent
      16             :    license, nor is any license granted by implication, estoppel or otherwise.
      17             : 
      18             :    Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
      19             :    contributions.
      20             : 
      21             :    This software is provided "AS IS", without any express or implied warranties. The software is in the
      22             :    development stage. It is intended exclusively for experts who have experience with such software and
      23             :    solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
      24             :    and fitness for a particular purpose are hereby disclaimed and excluded.
      25             : 
      26             :    Any dispute, controversy or claim arising under or in relation to providing this software shall be
      27             :    submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
      28             :    accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
      29             :    the United Nations Convention on Contracts on the International Sales of Goods.
      30             : 
      31             : *******************************************************************************************************/
      32             : 
      33             : /*====================================================================================
      34             :     EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
      35             :   ====================================================================================*/
      36             : 
      37             : #include <stdint.h>
      38             : #include "options.h"
      39             : #include "prot_fx.h"
      40             : #include "rom_com.h"
      41             : #include "wmc_auto.h"
      42             : 
      43             : /*-----------------------------------------------------------------*
      44             :  * Local constants
      45             :  *-----------------------------------------------------------------*/
      46             : 
      47             : #define N_MAX_FFT   1024
      48             : #define INV_SQR2_FX 23170 /*Q15*/
      49             : #define N_MAX_SAS   256
      50             : /*---------------------------------------------------------------------*
      51             :  * ifft_rel()
      52             :  *
      53             :  * Calculate the inverse FFT of a real signal
      54             :  *
      55             :  * Based on the FORTRAN code from the article "Real-valued Fast Fourier Transform Algorithms"
      56             :  * by Sorensen, ... in IEEE Trans. on ASSP, Vol. ASSP-35, No. June 6th 1987.
      57             :  *
      58             :  * Input: the io[] signal containing the spectrum in the following order :
      59             :  *
      60             :  * Re[0], Re[1], ..  Re[n/2], Im[n/2-1], .. Im[1]
      61             :  *---------------------------------------------------------------------*/
      62             : 
      63       14286 : void ifft_rel_fx(
      64             :     Word16 io[],    /* Qx i/o: input/output vector   */
      65             :     const Word16 n, /* Q0 i  : vector length         */
      66             :     const Word16 m  /* Q0 i  : log2 of vector length */
      67             : )
      68             : {
      69             :     Word16 i, j, k;
      70             :     Word16 step;
      71             :     Word16 n2, n4, n8, i0;
      72             :     Word16 is, id;
      73             :     Word16 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
      74             :     Word16 xt;
      75             :     Word16 r1;
      76             :     Word16 t1, t2, t3, t4, t5;
      77             :     const Word16 *s, *c, *s3, *c3;
      78             : 
      79             :     Word16 cc1, cc3, ss1, ss3;
      80             :     Word16 tmp;
      81             : #ifndef ISSUE_1836_replace_overflow_libcom
      82             : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
      83             :     Flag Overflow = 0;
      84             :     move16();
      85             : #endif
      86             : #endif
      87             : 
      88             : 
      89             :     /*-----------------------------------------------------------------*
      90             :      * ifft
      91             :      *-----------------------------------------------------------------*/
      92             : 
      93       14286 :     x = &io[-1];
      94       14286 :     n2 = shl( n, 1 );
      95       48563 :     FOR( k = 1; k < m; k++ )
      96             :     {
      97       34277 :         is = 0;
      98       34277 :         move16();
      99       34277 :         id = n2;
     100       34277 :         move16();
     101       34277 :         n2 = shr( n2, 1 );
     102       34277 :         n4 = shr( n2, 2 );
     103       34277 :         n8 = shr( n4, 1 );
     104       34277 :         tmp = sub( n, 1 );
     105       78823 :         WHILE( LT_16( is, tmp ) )
     106             :         {
     107       44546 :             xi1 = x + is + 1; /*Qx*/
     108       44546 :             xi2 = xi1 + n4;   /*Qx*/
     109       44546 :             xi3 = xi2 + n4;   /*Qx*/
     110       44546 :             xi4 = xi3 + n4;   /*Qx*/
     111             : 
     112      167821 :             FOR( i = is; i < n; i += id )
     113             :             {
     114             : #ifdef ISSUE_1836_replace_overflow_libcom
     115      123275 :                 t1 = sub_sat( *xi1, *xi3 );   /*Qx*/
     116      123275 :                 *xi1 = add_sat( *xi1, *xi3 ); /*Qx*/
     117      123275 :                 move16();
     118      123275 :                 *xi2 = shl_sat( *xi2, 1 ); /*Qx*/
     119      123275 :                 move16();
     120      123275 :                 *xi3 = sub_sat( t1, shl_sat( *xi4, 1 ) ); /*Qx*/
     121      123275 :                 move16();
     122      123275 :                 *xi4 = add_sat( t1, shl_sat( *xi4, 1 ) ); /*Qx*/
     123      123275 :                 move16();
     124             : #else
     125             :                 t1 = sub_o( *xi1, *xi3, &Overflow );   /*Qx*/
     126             :                 *xi1 = add_o( *xi1, *xi3, &Overflow ); /*Qx*/
     127             :                 move16();
     128             :                 *xi2 = shl_o( *xi2, 1, &Overflow ); /*Qx*/
     129             :                 move16();
     130             :                 *xi3 = sub_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
     131             :                 move16();
     132             :                 *xi4 = add_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
     133             :                 move16();
     134             : #endif
     135             : 
     136      123275 :                 IF( NE_16( n4, 1 ) )
     137             :                 {
     138             : #ifdef ISSUE_1836_replace_overflow_libcom
     139       61067 :                     t1 = mult_r( sub_sat( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
     140       61067 :                     t2 = mult_r( add_sat( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
     141             : 
     142       61067 :                     *( xi1 + n8 ) = add_sat( *( xi1 + n8 ), *( xi2 + n8 ) ); /*Qx*/
     143       61067 :                     move16();
     144       61067 :                     *( xi2 + n8 ) = sub_sat( *( xi4 + n8 ), *( xi3 + n8 ) ); /*Qx*/
     145       61067 :                     move16();
     146       61067 :                     *( xi3 + n8 ) = negate( shl_sat( add_sat( t2, t1 ), 1 ) ); /*Qx*/
     147       61067 :                     move16();
     148       61067 :                     *( xi4 + n8 ) = shl_sat( sub_sat( t1, t2 ), 1 ); /*Qx*/
     149       61067 :                     move16();
     150             : #else
     151             :                     t1 = mult_r( sub_o( *( xi2 + n8 ), *( xi1 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
     152             :                     t2 = mult_r( add_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
     153             : 
     154             :                     *( xi1 + n8 ) = add_o( *( xi1 + n8 ), *( xi2 + n8 ), &Overflow ); /*Qx*/
     155             :                     move16();
     156             :                     *( xi2 + n8 ) = sub_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ); /*Qx*/
     157             :                     move16();
     158             :                     *( xi3 + n8 ) = negate( shl_o( add_o( t2, t1, &Overflow ), 1, &Overflow ) ); /*Qx*/
     159             :                     move16();
     160             :                     *( xi4 + n8 ) = shl_o( sub_o( t1, t2, &Overflow ), 1, &Overflow ); /*Qx*/
     161             :                     move16();
     162             : #endif
     163             :                 }
     164      123275 :                 xi1 += id;
     165      123275 :                 xi2 += id;
     166      123275 :                 xi3 += id;
     167      123275 :                 xi4 += id;
     168             :             }
     169       44546 :             is = sub( shl( id, 1 ), n2 );
     170       44546 :             id = shl( id, 2 );
     171             :         }
     172             :         /*Can be acheived with a shr */
     173       34277 :         step = idiv1616( N_MAX_SAS, n2 );
     174       34277 :         move16();
     175             : 
     176       34277 :         s = sincos_t_fx + step;                /*Q15 */
     177       34277 :         c = s + 64;                            /*Q15 */
     178       34277 :         s3 = sincos_t_fx + i_mult2( step, 3 ); /*Q15 */
     179       34277 :         c3 = s3 + 64;                          /*Q15 */
     180       99314 :         FOR( j = 2; j <= n8; j++ )
     181             :         {
     182       65037 :             cc1 = *c; /*Q15 */
     183       65037 :             move16();
     184       65037 :             ss1 = *s; /*Q15 */
     185       65037 :             move16();
     186       65037 :             cc3 = *c3; /*Q15 */
     187       65037 :             move16();
     188       65037 :             ss3 = *s3; /*Q15 */
     189       65037 :             move16();
     190             : 
     191       65037 :             is = 0;
     192       65037 :             move16();
     193       65037 :             id = shl( n2, 1 );
     194             : 
     195       65037 :             c += step;
     196       65037 :             s += step;
     197             : 
     198       65037 :             c3 += imult1616( 3, step );
     199       65037 :             s3 += imult1616( 3, step );
     200      143766 :             WHILE( LT_16( is, sub( n, 1 ) ) )
     201             :             {
     202       78729 :                 xup1 = x + j + is;             /*Qx*/
     203       78729 :                 xup3 = xup1 + shl( n4, 1 );    /*Qx*/
     204       78729 :                 xdn6 = xup3 - shl( j, 1 ) + 2; /*Qx*/
     205             : 
     206       78729 :                 xdn8 = xdn6 + shl( n4, 1 ); /*Qx*/
     207             : 
     208      184842 :                 FOR( i = is; i < n; i += id )
     209             :                 {
     210             : #ifdef ISSUE_1836_replace_overflow_libcom
     211      106113 :                     t1 = sub_sat( *xup1, *xdn6 );    /*Qx*/
     212      106113 :                     *xup1 = add_sat( *xup1, *xdn6 ); /*Qx*/
     213      106113 :                     move16();
     214      106113 :                     xup1 += n4;
     215      106113 :                     xdn6 -= n4;
     216             : 
     217      106113 :                     t2 = sub_sat( *xdn6, *xup1 );    /*Qx*/
     218      106113 :                     *xdn6 = add_sat( *xup1, *xdn6 ); /*Qx*/
     219      106113 :                     move16();
     220             : 
     221      106113 :                     xdn6 += n4;
     222      106113 :                     t3 = add_sat( *xdn8, *xup3 );    /*Qx*/
     223      106113 :                     *xdn6 = sub_sat( *xdn8, *xup3 ); /*Qx*/
     224      106113 :                     move16();
     225             : 
     226      106113 :                     xup3 += n4;
     227      106113 :                     xdn8 -= n4;
     228             : 
     229      106113 :                     t4 = add_sat( *xup3, *xdn8 );    /*Qx*/
     230      106113 :                     *xup1 = sub_sat( *xup3, *xdn8 ); /*Qx*/
     231      106113 :                     move16();
     232             : 
     233      106113 :                     t5 = sub_sat( t1, t4 );                                  /*Qx*/
     234      106113 :                     t1 = add_sat( t1, t4 );                                  /*Qx*/
     235      106113 :                     t4 = sub_sat( t2, t3 );                                  /*Qx*/
     236      106113 :                     t2 = add_sat( t2, t3 );                                  /*Qx*/
     237      106113 :                     *xup3 = sub_sat( mult_r( t1, cc3 ), mult_r( t2, ss3 ) ); /*Qx*/
     238      106113 :                     move16();
     239      106113 :                     xup3 -= n4;
     240      106113 :                     *xup3 = add_sat( mult_r( t5, cc1 ), mult_r( t4, ss1 ) ); /*Qx*/
     241      106113 :                     move16();
     242      106113 :                     *xdn8 = sub_sat( mult_r( t5, ss1 ), mult_r( t4, cc1 ) ); /*Qx*/
     243      106113 :                     move16();
     244             : 
     245      106113 :                     xdn8 += n4;
     246      106113 :                     *xdn8 = add_sat( mult_r( t2, cc3 ), mult_r( t1, ss3 ) ); /*Qx*/
     247      106113 :                     move16();
     248             : #else
     249             :                     t1 = sub_o( *xup1, *xdn6, &Overflow );    /*Qx*/
     250             :                     *xup1 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
     251             :                     move16();
     252             :                     xup1 += n4;
     253             :                     xdn6 -= n4;
     254             : 
     255             :                     t2 = sub_o( *xdn6, *xup1, &Overflow );    /*Qx*/
     256             :                     *xdn6 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
     257             :                     move16();
     258             : 
     259             :                     xdn6 += n4;
     260             :                     t3 = add_o( *xdn8, *xup3, &Overflow );    /*Qx*/
     261             :                     *xdn6 = sub_o( *xdn8, *xup3, &Overflow ); /*Qx*/
     262             :                     move16();
     263             : 
     264             :                     xup3 += n4;
     265             :                     xdn8 -= n4;
     266             : 
     267             :                     t4 = add_o( *xup3, *xdn8, &Overflow );    /*Qx*/
     268             :                     *xup1 = sub_o( *xup3, *xdn8, &Overflow ); /*Qx*/
     269             :                     move16();
     270             : 
     271             :                     t5 = sub_o( t1, t4, &Overflow );                                  /*Qx*/
     272             :                     t1 = add_o( t1, t4, &Overflow );                                  /*Qx*/
     273             :                     t4 = sub_o( t2, t3, &Overflow );                                  /*Qx*/
     274             :                     t2 = add_o( t2, t3, &Overflow );                                  /*Qx*/
     275             :                     *xup3 = sub_o( mult_r( t1, cc3 ), mult_r( t2, ss3 ), &Overflow ); /*Qx*/
     276             :                     move16();
     277             :                     xup3 -= n4;
     278             :                     *xup3 = add_o( mult_r( t5, cc1 ), mult_r( t4, ss1 ), &Overflow ); /*Qx*/
     279             :                     move16();
     280             :                     *xdn8 = sub_o( mult_r( t5, ss1 ), mult_r( t4, cc1 ), &Overflow ); /*Qx*/
     281             :                     move16();
     282             : 
     283             :                     xdn8 += n4;
     284             :                     *xdn8 = add_o( mult_r( t2, cc3 ), mult_r( t1, ss3 ), &Overflow ); /*Qx*/
     285             :                     move16();
     286             : #endif
     287             : 
     288      106113 :                     xup1 -= n4;
     289      106113 :                     xup1 += id;
     290      106113 :                     xup3 += id;
     291      106113 :                     xdn6 += id;
     292      106113 :                     xdn8 += id;
     293             :                 }
     294       78729 :                 is = sub( shl( id, 1 ), n2 );
     295       78729 :                 id = shl( id, 2 );
     296             :             }
     297             :         }
     298             :     }
     299             : 
     300             :     /*-----------------------------------------------------------------*
     301             :      * Length two butterflies
     302             :      *-----------------------------------------------------------------*/
     303             : 
     304       14286 :     is = 1;
     305       14286 :     move16();
     306       14286 :     id = 4;
     307       14286 :     move16();
     308       45140 :     WHILE( is < n )
     309             :     {
     310       30854 :         xi0 = x + is;
     311       30854 :         xi1 = xi0 + 1;
     312             : 
     313      167274 :         FOR( i0 = is; i0 <= n; i0 += id )
     314             :         {
     315      136420 :             r1 = *xi0;
     316      136420 :             move16();
     317             : #ifdef ISSUE_1836_replace_overflow_libcom
     318      136420 :             *xi0 = add_sat( r1, *xi1 ); /*Qx*/
     319      136420 :             move16();
     320      136420 :             *xi1 = sub_sat( r1, *xi1 ); /*Qx*/
     321      136420 :             move16();
     322             : #else
     323             :             *xi0 = add_o( r1, *xi1, &Overflow ); /*Qx*/
     324             :             move16();
     325             :             *xi1 = sub_o( r1, *xi1, &Overflow ); /*Qx*/
     326             :             move16();
     327             : #endif
     328      136420 :             xi0 += id;
     329      136420 :             xi1 += id;
     330             :         }
     331       30854 :         is = sub( shl( id, 1 ), 1 );
     332       30854 :         id = shl( id, 2 );
     333             :     }
     334             : 
     335             :     /*-----------------------------------------------------------------*
     336             :      * Digit reverse counter
     337             :      *-----------------------------------------------------------------*/
     338             : 
     339       14286 :     j = 1;
     340       14286 :     move16();
     341      397256 :     FOR( i = 1; i < n; i++ )
     342             :     {
     343      382970 :         IF( LT_16( i, j ) )
     344             :         {
     345      163210 :             xt = x[j]; /*Qx*/
     346      163210 :             move16();
     347      163210 :             x[j] = x[i]; /*Qx*/
     348      163210 :             move16();
     349      163210 :             x[i] = xt; /*Qx*/
     350      163210 :             move16();
     351             :         }
     352      382970 :         k = shr( n, 1 );
     353      717377 :         WHILE( LT_16( k, j ) )
     354             :         {
     355      334407 :             j = sub( j, k );
     356      334407 :             k = shr( k, 1 );
     357             :         }
     358      382970 :         j = add( j, k );
     359             :     }
     360             : 
     361             :     /*-----------------------------------------------------------------*
     362             :      * Normalization
     363             :      *-----------------------------------------------------------------*/
     364             : 
     365       14286 :     tmp = div_s( 1, n ); /*Q15 */
     366      411542 :     FOR( i = 1; i <= n; i++ )
     367             :     {
     368      397256 :         x[i] = mult_r( x[i], tmp ); /*Qx*/
     369      397256 :         move16();
     370             :     }
     371             : 
     372       14286 :     return;
     373             : }
     374             : 
     375             : #define INV_SQRT_2_16 ( Word16 )( 0x5A82 ) /*Q15*/
     376       34502 : void ifft_rel_fx32(
     377             :     Word32 io[],    /* Qx i/o: input/output vector   */
     378             :     const Word16 n, /* Q0 i  : vector length         */
     379             :     const Word16 m  /* Q0 i  : log2 of vector length */
     380             : )
     381             : {
     382             :     Word16 i, j, k;
     383             :     Word16 step;
     384             :     Word16 n2, n4, n8, i0;
     385             :     Word16 is, id;
     386             :     Word32 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
     387             :     Word32 xt;
     388             :     Word32 r1;
     389             :     Word32 t1, t2, t3, t4, t5;
     390             :     Word16 cc1, cc3, ss1, ss3;
     391             :     const Word16 *s, *s3, *c, *c3;
     392             :     const Word16 *idx;
     393             :     Word32 temp[512];
     394       34502 :     Word16 n_inv = 128; /*1/256 in Q15*/
     395       34502 :     move16();
     396             : 
     397       34502 :     SWITCH( n )
     398             :     {
     399           0 :         case 128:
     400           0 :             n_inv = 256; /*1/128 in Q15*/
     401           0 :             BREAK;
     402         244 :         case 256:
     403         244 :             n_inv = 128; /*1/256 in Q15*/
     404         244 :             BREAK;
     405       34258 :         case 512:
     406       34258 :             n_inv = 64; /*1/512 in Q15*/
     407       34258 :             BREAK;
     408           0 :         default:
     409           0 :             assert( 0 );
     410             :             BREAK;
     411             :     }
     412       34502 :     move16();
     413             : 
     414             :     /*-----------------------------------------------------------------*
     415             :      * IFFT
     416             :      *-----------------------------------------------------------------*/
     417             : 
     418       34502 :     x = &io[-1];
     419       34502 :     n2 = shl( n, 1 ); /*Q0*/
     420      310274 :     FOR( k = 1; k < m; k++ )
     421             :     {
     422      275772 :         is = 0;
     423      275772 :         move16();
     424      275772 :         id = n2;
     425      275772 :         move16();
     426      275772 :         n2 = shr( n2, 1 ); /*Q0*/
     427      275772 :         n4 = shr( n2, 2 ); /*Q0*/
     428      275772 :         n8 = shr( n4, 1 ); /*Q0*/
     429      964836 :         WHILE( LT_16( is, sub( n, 1 ) ) )
     430             :         {
     431      689064 :             xi1 = x + is + 1; /*Qx*/
     432      689064 :             xi2 = xi1 + n4;   /*Qx*/
     433      689064 :             xi3 = xi2 + n4;   /*Qx*/
     434      689064 :             xi4 = xi3 + n4;   /*Qx*/
     435             : 
     436     6533664 :             FOR( i = is; i < n; i += id )
     437             :             {
     438     5844600 :                 t1 = L_sub( *xi1, *xi3 );   /*Qx*/
     439     5844600 :                 *xi1 = L_add( *xi1, *xi3 ); /*Qx*/
     440     5844600 :                 move32();
     441     5844600 :                 *xi2 = L_shl( *xi2, 1 ); /*Qx*/
     442     5844600 :                 move32();
     443     5844600 :                 *xi3 = L_sub( t1, L_shl( *xi4, 1 ) ); /*Qx*/
     444     5844600 :                 move32();
     445     5844600 :                 *xi4 = L_add( t1, L_shl( *xi4, 1 ) ); /*Qx*/
     446     5844600 :                 move32();
     447     5844600 :                 IF( NE_16( n4, 1 ) )
     448             :                 {
     449     2922178 :                     t1 = Mpy_32_16_1( L_sub( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
     450     2922178 :                     t2 = Mpy_32_16_1( L_add( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
     451             : 
     452     2922178 :                     *( xi1 + n8 ) = L_add( *( xi1 + n8 ), *( xi2 + n8 ) ); /*Qx*/
     453     2922178 :                     move32();
     454     2922178 :                     *( xi2 + n8 ) = L_sub( *( xi4 + n8 ), *( xi3 + n8 ) ); /*Qx*/
     455     2922178 :                     move32();
     456     2922178 :                     *( xi3 + n8 ) = L_shl( L_negate( L_add( t2, t1 ) ), 1 ); /*Qx*/
     457     2922178 :                     move32();
     458     2922178 :                     *( xi4 + n8 ) = L_shl( L_sub( t1, t2 ), 1 ); /*Qx*/
     459     2922178 :                     move32();
     460             :                 }
     461     5844600 :                 xi1 += id;
     462     5844600 :                 xi2 += id;
     463     5844600 :                 xi3 += id;
     464     5844600 :                 xi4 += id;
     465             :             }
     466      689064 :             is = sub( shl( id, 1 ), n2 ); /*Q0*/
     467      689064 :             id = shl( id, 2 );            /*Q0*/
     468             :         }
     469             :         /*Can be acheived with a shr */
     470      275772 :         step = idiv1616( N_MAX_FFT, n2 );
     471      275772 :         move16();
     472             : 
     473      275772 :         s = sincos_t_ext_fx + step;                  /*Q15*/
     474      275772 :         c = s + shr( N_MAX_FFT, 2 );                 /*Q15*/
     475      275772 :         s3 = sincos_t_ext_fx + imult1616( 3, step ); /*Q15*/
     476      275772 :         c3 = s3 + shr( N_MAX_FFT, 2 );               /*Q15*/
     477     4400640 :         FOR( j = 2; j <= n8; j++ )
     478             :         {
     479     4124868 :             cc1 = *c;  /*Q15*/
     480     4124868 :             ss1 = *s;  /*Q15*/
     481     4124868 :             cc3 = *c3; /*Q15*/
     482     4124868 :             ss3 = *s3; /*Q15*/
     483     4124868 :             move16();
     484     4124868 :             move16();
     485     4124868 :             move16();
     486     4124868 :             move16();
     487             : 
     488     4124868 :             is = 0;
     489     4124868 :             move16();
     490     4124868 :             id = shl( n2, 1 );
     491     4124868 :             move16();
     492             : 
     493     4124868 :             c += step;
     494     4124868 :             s += step;
     495             : 
     496     4124868 :             c3 += imult1616( 3, step ); /*Q15*/
     497     4124868 :             s3 += imult1616( 3, step ); /*Q15*/
     498     9280404 :             WHILE( LT_16( is, sub( n, 1 ) ) )
     499             :             {
     500     5155536 :                 xup1 = x + add( j, is );             /*Qx*/
     501     5155536 :                 xup3 = xup1 + shl( n4, 1 );          /*Qx*/
     502     5155536 :                 xdn6 = xup3 - sub( shl( j, 1 ), 2 ); /*Qx*/
     503     5155536 :                 xdn8 = xdn6 + shl( n4, 1 );          /*Qx*/
     504             : 
     505    12989052 :                 FOR( i = is; i < n; i += id )
     506             :                 {
     507     7833516 :                     t1 = L_sub( *xup1, *xdn6 );    /*Qx*/
     508     7833516 :                     *xup1 = L_add( *xup1, *xdn6 ); /*Qx*/
     509     7833516 :                     move32();
     510     7833516 :                     xup1 += n4;
     511     7833516 :                     xdn6 -= n4;
     512             : 
     513     7833516 :                     t2 = L_sub( *xdn6, *xup1 );    /*Qx*/
     514     7833516 :                     *xdn6 = L_add( *xup1, *xdn6 ); /*Qx*/
     515     7833516 :                     move32();
     516             : 
     517     7833516 :                     xdn6 += n4;
     518     7833516 :                     t3 = L_add( *xdn8, *xup3 );    /*Qx*/
     519     7833516 :                     *xdn6 = L_sub( *xdn8, *xup3 ); /*Qx*/
     520     7833516 :                     move32();
     521             : 
     522     7833516 :                     xup3 += n4;
     523     7833516 :                     xdn8 -= n4;
     524             : 
     525     7833516 :                     t4 = L_add( *xup3, *xdn8 );    /*Qx*/
     526     7833516 :                     *xup1 = L_sub( *xup3, *xdn8 ); /*Qx*/
     527     7833516 :                     move32();
     528             : 
     529     7833516 :                     t5 = L_sub( t1, t4 );                                            /*Qx*/
     530     7833516 :                     t1 = L_add( t1, t4 );                                            /*Qx*/
     531     7833516 :                     t4 = L_sub( t2, t3 );                                            /*Qx*/
     532     7833516 :                     t2 = L_add( t2, t3 );                                            /*Qx*/
     533     7833516 :                     *xup3 = L_sub( Mpy_32_16_1( t1, cc3 ), Mpy_32_16_1( t2, ss3 ) ); /*Qx*/
     534     7833516 :                     move32();
     535     7833516 :                     xup3 -= n4;
     536     7833516 :                     *xup3 = L_add( Mpy_32_16_1( t5, cc1 ), Mpy_32_16_1( t4, ss1 ) ); /*Qx*/
     537     7833516 :                     move32();
     538     7833516 :                     *xdn8 = L_sub( Mpy_32_16_1( t5, ss1 ), Mpy_32_16_1( t4, cc1 ) ); /*Qx*/
     539     7833516 :                     move32();
     540             : 
     541     7833516 :                     xdn8 += n4;
     542     7833516 :                     *xdn8 = L_add( Mpy_32_16_1( t2, cc3 ), Mpy_32_16_1( t1, ss3 ) ); /*Qx*/
     543     7833516 :                     move32();
     544             : 
     545     7833516 :                     xup1 -= n4;
     546     7833516 :                     xup1 += id;
     547     7833516 :                     xup3 += id;
     548     7833516 :                     xdn6 += id;
     549     7833516 :                     xdn8 += id;
     550             :                 }
     551     5155536 :                 is = sub( shl( id, 1 ), n2 ); /*Q0*/
     552     5155536 :                 id = shl( id, 2 );            /*Q0*/
     553             :             }
     554             :         }
     555             :     }
     556             : 
     557             :     /*-----------------------------------------------------------------*
     558             :      * Length two butterflies
     559             :      *-----------------------------------------------------------------*/
     560             : 
     561       34502 :     is = 1;
     562       34502 :     move16();
     563       34502 :     id = 4;
     564       34502 :     move16();
     565      206768 :     WHILE( LT_16( is, n ) )
     566             :     {
     567      172266 :         xi0 = x + is;
     568      172266 :         xi1 = xi0 + 1;
     569             : 
     570     6051124 :         FOR( i0 = is; i0 <= n; i0 += id )
     571             :         {
     572     5878858 :             r1 = *xi0; /*Qx*/
     573     5878858 :             move32();
     574     5878858 :             *xi0 = L_add( r1, *xi1 ); /*Qx*/
     575     5878858 :             move32();
     576     5878858 :             *xi1 = L_sub( r1, *xi1 ); /*Qx*/
     577     5878858 :             move32();
     578     5878858 :             xi0 += id;
     579     5878858 :             xi1 += id;
     580             :         }
     581      172266 :         is = sub( shl( id, 1 ), 1 );
     582      172266 :         id = shl( id, 2 );
     583             :     }
     584             : 
     585             :     /*-----------------------------------------------------------------*
     586             :      * Digit reverse counter
     587             :      *-----------------------------------------------------------------*/
     588             : 
     589       34502 :     idx = fft256_read_indexes;
     590       34502 :     xi0 = &temp[0] - 1;
     591       34502 :     IF( EQ_16( n, 128 ) )
     592             :     {
     593           0 :         FOR( i = 0; i < n; i++ )
     594             :         {
     595           0 :             j = *idx++;
     596           0 :             move16();
     597           0 :             temp[i] = x[1 + shr( j, 1 )]; /*Qx*/
     598           0 :             move32();
     599             :         }
     600             :     }
     601       34502 :     ELSE IF( EQ_16( n, 256 ) )
     602             :     {
     603       62708 :         FOR( i = 0; i < n; i++ )
     604             :         {
     605       62464 :             j = *idx++;
     606       62464 :             temp[i] = x[1 + j]; /*Qx*/
     607       62464 :             move32();
     608             :         }
     609             :     }
     610       34258 :     ELSE IF( EQ_16( n, 512 ) )
     611             :     {
     612     8804306 :         FOR( i = 0; i < 256; i++ )
     613             :         {
     614     8770048 :             j = *idx++;
     615     8770048 :             temp[i] = x[1 + 2 * j]; /*Qx*/
     616     8770048 :             move32();
     617     8770048 :             temp[i + 256] = x[2 + 2 * j]; /*Qx*/
     618     8770048 :             move32();
     619             :         }
     620             :     }
     621             :     ELSE
     622             :     {
     623           0 :         xi0 = x;
     624           0 :         j = 1;
     625           0 :         move16();
     626           0 :         FOR( i = 1; i < n; i++ )
     627             :         {
     628           0 :             IF( LT_16( i, j ) )
     629             :             {
     630           0 :                 xt = x[j];   /*Qx*/
     631           0 :                 x[j] = x[i]; /*Qx*/
     632           0 :                 x[i] = xt;   /*Qx*/
     633           0 :                 move32();
     634           0 :                 move32();
     635           0 :                 move32();
     636             :             }
     637           0 :             k = shr( n, 1 );
     638           0 :             WHILE( LT_16( k, j ) )
     639             :             {
     640           0 :                 j = sub( j, k );
     641           0 :                 k = shr( k, 1 );
     642             :             }
     643           0 :             j = add( j, k );
     644             :         }
     645             :     }
     646             : 
     647             :     /*-----------------------------------------------------------------*
     648             :      * Normalization
     649             :      *-----------------------------------------------------------------*/
     650             : 
     651    17637062 :     FOR( i = 1; i <= n; i++ )
     652             :     {
     653    17602560 :         x[i] = Mpy_32_16_1( xi0[i], n_inv ); /*Qx*/
     654    17602560 :         move32();
     655             :     }
     656             : 
     657       34502 :     return;
     658             : }

Generated by: LCOV version 1.14