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 : * Local constants
44 : *-----------------------------------------------------------------*/
45 :
46 : #define N_MAX_FFT 1024
47 : #define INV_SQR2_FX 23170 /*Q15*/
48 : #define N_MAX_SAS 256
49 : /*---------------------------------------------------------------------*
50 : * ifft_rel()
51 : *
52 : * Calculate the inverse FFT of a real signal
53 : *
54 : * Based on the FORTRAN code from the article "Real-valued Fast Fourier Transform Algorithms"
55 : * by Sorensen, ... in IEEE Trans. on ASSP, Vol. ASSP-35, No. June 6th 1987.
56 : *
57 : * Input: the io[] signal containing the spectrum in the following order :
58 : *
59 : * Re[0], Re[1], .. Re[n/2], Im[n/2-1], .. Im[1]
60 : *---------------------------------------------------------------------*/
61 :
62 31262 : void ifft_rel_fx(
63 : Word16 io[], /* Qx i/o: input/output vector */
64 : const Word16 n, /* Q0 i : vector length */
65 : const Word16 m /* Q0 i : log2 of vector length */
66 : )
67 : {
68 : Word16 i, j, k;
69 : Word16 step;
70 : Word16 n2, n4, n8, i0;
71 : Word16 is, id;
72 : Word16 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
73 : Word16 xt;
74 : Word16 r1;
75 : Word16 t1, t2, t3, t4, t5;
76 : const Word16 *s, *c, *s3, *c3;
77 :
78 : Word16 cc1, cc3, ss1, ss3;
79 : Word16 tmp;
80 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
81 31262 : Flag Overflow = 0;
82 31262 : move16();
83 : #endif
84 :
85 :
86 : /*-----------------------------------------------------------------*
87 : * ifft
88 : *-----------------------------------------------------------------*/
89 :
90 31262 : x = &io[-1];
91 31262 : n2 = shl( n, 1 );
92 111696 : FOR( k = 1; k < m; k++ )
93 : {
94 80434 : is = 0;
95 80434 : move16();
96 80434 : id = n2;
97 80434 : move16();
98 80434 : n2 = shr( n2, 1 );
99 80434 : n4 = shr( n2, 2 );
100 80434 : n8 = shr( n4, 1 );
101 80434 : tmp = sub( n, 1 );
102 193106 : WHILE( LT_16( is, tmp ) )
103 : {
104 112672 : xi1 = x + is + 1; /*Qx*/
105 112672 : xi2 = xi1 + n4; /*Qx*/
106 112672 : xi3 = xi2 + n4; /*Qx*/
107 112672 : xi4 = xi3 + n4; /*Qx*/
108 :
109 472502 : FOR( i = is; i < n; i += id )
110 : {
111 359830 : t1 = sub_o( *xi1, *xi3, &Overflow ); /*Qx*/
112 359830 : *xi1 = add_o( *xi1, *xi3, &Overflow ); /*Qx*/
113 359830 : move16();
114 359830 : *xi2 = shl_o( *xi2, 1, &Overflow ); /*Qx*/
115 359830 : move16();
116 359830 : *xi3 = sub_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
117 359830 : move16();
118 359830 : *xi4 = add_o( t1, shl_o( *xi4, 1, &Overflow ), &Overflow ); /*Qx*/
119 359830 : move16();
120 :
121 359830 : IF( NE_16( n4, 1 ) )
122 : {
123 178124 : t1 = mult_r( sub_o( *( xi2 + n8 ), *( xi1 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
124 178124 : t2 = mult_r( add_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ), INV_SQR2_FX /*Q15*/ ); /*Qx*/
125 :
126 178124 : *( xi1 + n8 ) = add_o( *( xi1 + n8 ), *( xi2 + n8 ), &Overflow ); /*Qx*/
127 178124 : move16();
128 178124 : *( xi2 + n8 ) = sub_o( *( xi4 + n8 ), *( xi3 + n8 ), &Overflow ); /*Qx*/
129 178124 : move16();
130 178124 : *( xi3 + n8 ) = negate( shl_o( add_o( t2, t1, &Overflow ), 1, &Overflow ) ); /*Qx*/
131 178124 : move16();
132 178124 : *( xi4 + n8 ) = shl_o( sub_o( t1, t2, &Overflow ), 1, &Overflow ); /*Qx*/
133 178124 : move16();
134 : }
135 359830 : xi1 += id;
136 359830 : xi2 += id;
137 359830 : xi3 += id;
138 359830 : xi4 += id;
139 : }
140 112672 : is = sub( shl( id, 1 ), n2 );
141 112672 : id = shl( id, 2 );
142 : }
143 : /*Can be acheived with a shr */
144 80434 : step = idiv1616( N_MAX_SAS, n2 );
145 80434 : move16();
146 :
147 80434 : s = sincos_t_fx + step; /*Q15 */
148 80434 : c = s + 64; /*Q15 */
149 80434 : s3 = sincos_t_fx + i_mult2( step, 3 ); /*Q15 */
150 80434 : c3 = s3 + 64; /*Q15 */
151 284608 : FOR( j = 2; j <= n8; j++ )
152 : {
153 204174 : cc1 = *c; /*Q15 */
154 204174 : move16();
155 204174 : ss1 = *s; /*Q15 */
156 204174 : move16();
157 204174 : cc3 = *c3; /*Q15 */
158 204174 : move16();
159 204174 : ss3 = *s3; /*Q15 */
160 204174 : move16();
161 :
162 204174 : is = 0;
163 204174 : move16();
164 204174 : id = shl( n2, 1 );
165 :
166 204174 : c += step;
167 204174 : s += step;
168 :
169 204174 : c3 += imult1616( 3, step );
170 204174 : s3 += imult1616( 3, step );
171 451332 : WHILE( LT_16( is, sub( n, 1 ) ) )
172 : {
173 247158 : xup1 = x + j + is; /*Qx*/
174 247158 : xup3 = xup1 + shl( n4, 1 ); /*Qx*/
175 247158 : xdn6 = xup3 - shl( j, 1 ) + 2; /*Qx*/
176 :
177 247158 : xdn8 = xdn6 + shl( n4, 1 ); /*Qx*/
178 :
179 580284 : FOR( i = is; i < n; i += id )
180 : {
181 333126 : t1 = sub_o( *xup1, *xdn6, &Overflow ); /*Qx*/
182 333126 : *xup1 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
183 333126 : move16();
184 333126 : xup1 += n4;
185 333126 : xdn6 -= n4;
186 :
187 333126 : t2 = sub_o( *xdn6, *xup1, &Overflow ); /*Qx*/
188 333126 : *xdn6 = add_o( *xup1, *xdn6, &Overflow ); /*Qx*/
189 333126 : move16();
190 :
191 333126 : xdn6 += n4;
192 333126 : t3 = add_o( *xdn8, *xup3, &Overflow ); /*Qx*/
193 333126 : *xdn6 = sub_o( *xdn8, *xup3, &Overflow ); /*Qx*/
194 333126 : move16();
195 :
196 333126 : xup3 += n4;
197 333126 : xdn8 -= n4;
198 :
199 333126 : t4 = add_o( *xup3, *xdn8, &Overflow ); /*Qx*/
200 333126 : *xup1 = sub_o( *xup3, *xdn8, &Overflow ); /*Qx*/
201 333126 : move16();
202 :
203 333126 : t5 = sub_o( t1, t4, &Overflow ); /*Qx*/
204 333126 : t1 = add_o( t1, t4, &Overflow ); /*Qx*/
205 333126 : t4 = sub_o( t2, t3, &Overflow ); /*Qx*/
206 333126 : t2 = add_o( t2, t3, &Overflow ); /*Qx*/
207 333126 : *xup3 = sub_o( mult_r( t1, cc3 ), mult_r( t2, ss3 ), &Overflow ); /*Qx*/
208 333126 : move16();
209 333126 : xup3 -= n4;
210 333126 : *xup3 = add_o( mult_r( t5, cc1 ), mult_r( t4, ss1 ), &Overflow ); /*Qx*/
211 333126 : move16();
212 333126 : *xdn8 = sub_o( mult_r( t5, ss1 ), mult_r( t4, cc1 ), &Overflow ); /*Qx*/
213 333126 : move16();
214 :
215 333126 : xdn8 += n4;
216 333126 : *xdn8 = add_o( mult_r( t2, cc3 ), mult_r( t1, ss3 ), &Overflow ); /*Qx*/
217 333126 : move16();
218 :
219 333126 : xup1 -= n4;
220 333126 : xup1 += id;
221 333126 : xup3 += id;
222 333126 : xdn6 += id;
223 333126 : xdn8 += id;
224 : }
225 247158 : is = sub( shl( id, 1 ), n2 );
226 247158 : id = shl( id, 2 );
227 : }
228 : }
229 : }
230 :
231 : /*-----------------------------------------------------------------*
232 : * Length two butterflies
233 : *-----------------------------------------------------------------*/
234 :
235 31262 : is = 1;
236 31262 : move16();
237 31262 : id = 4;
238 31262 : move16();
239 100950 : WHILE( is < n )
240 : {
241 69688 : xi0 = x + is;
242 69688 : xi1 = xi0 + 1;
243 :
244 457198 : FOR( i0 = is; i0 <= n; i0 += id )
245 : {
246 387510 : r1 = *xi0;
247 387510 : move16();
248 387510 : *xi0 = add_o( r1, *xi1, &Overflow ); /*Qx*/
249 387510 : move16();
250 387510 : *xi1 = sub_o( r1, *xi1, &Overflow ); /*Qx*/
251 387510 : move16();
252 387510 : xi0 += id;
253 387510 : xi1 += id;
254 : }
255 69688 : is = sub( shl( id, 1 ), 1 );
256 69688 : id = shl( id, 2 );
257 : }
258 :
259 : /*-----------------------------------------------------------------*
260 : * Digit reverse counter
261 : *-----------------------------------------------------------------*/
262 :
263 31262 : j = 1;
264 31262 : move16();
265 1138432 : FOR( i = 1; i < n; i++ )
266 : {
267 1107170 : IF( LT_16( i, j ) )
268 : {
269 485200 : xt = x[j]; /*Qx*/
270 485200 : move16();
271 485200 : x[j] = x[i]; /*Qx*/
272 485200 : move16();
273 485200 : x[i] = xt; /*Qx*/
274 485200 : move16();
275 : }
276 1107170 : k = shr( n, 1 );
277 2102644 : WHILE( LT_16( k, j ) )
278 : {
279 995474 : j = sub( j, k );
280 995474 : k = shr( k, 1 );
281 : }
282 1107170 : j = add( j, k );
283 : }
284 :
285 : /*-----------------------------------------------------------------*
286 : * Normalization
287 : *-----------------------------------------------------------------*/
288 :
289 31262 : tmp = div_s( 1, n ); /*Q15 */
290 1169694 : FOR( i = 1; i <= n; i++ )
291 : {
292 1138432 : x[i] = mult_r( x[i], tmp ); /*Qx*/
293 1138432 : move16();
294 : }
295 :
296 31262 : return;
297 : }
298 :
299 : #define INV_SQRT_2_16 ( Word16 )( 0x5A82 ) /*Q15*/
300 34067 : void ifft_rel_fx32(
301 : Word32 io[], /* Qx i/o: input/output vector */
302 : const Word16 n, /* Q0 i : vector length */
303 : const Word16 m /* Q0 i : log2 of vector length */
304 : )
305 : {
306 : Word16 i, j, k;
307 : Word16 step;
308 : Word16 n2, n4, n8, i0;
309 : Word16 is, id;
310 : Word32 *x, *xi0, *xi1, *xi2, *xi3, *xi4, *xup1, *xdn6, *xup3, *xdn8;
311 : Word32 xt;
312 : Word32 r1;
313 : Word32 t1, t2, t3, t4, t5;
314 : Word16 cc1, cc3, ss1, ss3;
315 : const Word16 *s, *s3, *c, *c3;
316 : const Word16 *idx;
317 : Word32 temp[512];
318 34067 : Word16 n_inv = 128; /*1/256 in Q15*/
319 34067 : move16();
320 :
321 34067 : SWITCH( n )
322 : {
323 0 : case 128:
324 0 : n_inv = 256; /*1/128 in Q15*/
325 0 : BREAK;
326 244 : case 256:
327 244 : n_inv = 128; /*1/256 in Q15*/
328 244 : BREAK;
329 33823 : case 512:
330 33823 : n_inv = 64; /*1/512 in Q15*/
331 33823 : BREAK;
332 0 : default:
333 0 : assert( 0 );
334 : BREAK;
335 : }
336 34067 : move16();
337 :
338 : /*-----------------------------------------------------------------*
339 : * IFFT
340 : *-----------------------------------------------------------------*/
341 :
342 34067 : x = &io[-1];
343 34067 : n2 = shl( n, 1 ); /*Q0*/
344 306359 : FOR( k = 1; k < m; k++ )
345 : {
346 272292 : is = 0;
347 272292 : move16();
348 272292 : id = n2;
349 272292 : move16();
350 272292 : n2 = shr( n2, 1 ); /*Q0*/
351 272292 : n4 = shr( n2, 2 ); /*Q0*/
352 272292 : n8 = shr( n4, 1 ); /*Q0*/
353 952656 : WHILE( LT_16( is, sub( n, 1 ) ) )
354 : {
355 680364 : xi1 = x + is + 1; /*Qx*/
356 680364 : xi2 = xi1 + n4; /*Qx*/
357 680364 : xi3 = xi2 + n4; /*Qx*/
358 680364 : xi4 = xi3 + n4; /*Qx*/
359 :
360 6451014 : FOR( i = is; i < n; i += id )
361 : {
362 5770650 : t1 = L_sub( *xi1, *xi3 ); /*Qx*/
363 5770650 : *xi1 = L_add( *xi1, *xi3 ); /*Qx*/
364 5770650 : move32();
365 5770650 : *xi2 = L_shl( *xi2, 1 ); /*Qx*/
366 5770650 : move32();
367 5770650 : *xi3 = L_sub( t1, L_shl( *xi4, 1 ) ); /*Qx*/
368 5770650 : move32();
369 5770650 : *xi4 = L_add( t1, L_shl( *xi4, 1 ) ); /*Qx*/
370 5770650 : move32();
371 5770650 : IF( NE_16( n4, 1 ) )
372 : {
373 2885203 : t1 = Mpy_32_16_1( L_sub( *( xi2 + n8 ), *( xi1 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
374 2885203 : t2 = Mpy_32_16_1( L_add( *( xi4 + n8 ), *( xi3 + n8 ) ), INV_SQRT_2_16 ); /*Qx*/
375 :
376 2885203 : *( xi1 + n8 ) = L_add( *( xi1 + n8 ), *( xi2 + n8 ) ); /*Qx*/
377 2885203 : move32();
378 2885203 : *( xi2 + n8 ) = L_sub( *( xi4 + n8 ), *( xi3 + n8 ) ); /*Qx*/
379 2885203 : move32();
380 2885203 : *( xi3 + n8 ) = L_shl( L_negate( L_add( t2, t1 ) ), 1 ); /*Qx*/
381 2885203 : move32();
382 2885203 : *( xi4 + n8 ) = L_shl( L_sub( t1, t2 ), 1 ); /*Qx*/
383 2885203 : move32();
384 : }
385 5770650 : xi1 += id;
386 5770650 : xi2 += id;
387 5770650 : xi3 += id;
388 5770650 : xi4 += id;
389 : }
390 680364 : is = sub( shl( id, 1 ), n2 ); /*Q0*/
391 680364 : id = shl( id, 2 ); /*Q0*/
392 : }
393 : /*Can be acheived with a shr */
394 272292 : step = idiv1616( N_MAX_FFT, n2 );
395 272292 : move16();
396 :
397 272292 : s = sincos_t_ext_fx + step; /*Q15*/
398 272292 : c = s + shr( N_MAX_FFT, 2 ); /*Q15*/
399 272292 : s3 = sincos_t_ext_fx + imult1616( 3, step ); /*Q15*/
400 272292 : c3 = s3 + shr( N_MAX_FFT, 2 ); /*Q15*/
401 4344960 : FOR( j = 2; j <= n8; j++ )
402 : {
403 4072668 : cc1 = *c; /*Q15*/
404 4072668 : ss1 = *s; /*Q15*/
405 4072668 : cc3 = *c3; /*Q15*/
406 4072668 : ss3 = *s3; /*Q15*/
407 4072668 : move16();
408 4072668 : move16();
409 4072668 : move16();
410 4072668 : move16();
411 :
412 4072668 : is = 0;
413 4072668 : move16();
414 4072668 : id = shl( n2, 1 );
415 4072668 : move16();
416 :
417 4072668 : c += step;
418 4072668 : s += step;
419 :
420 4072668 : c3 += imult1616( 3, step ); /*Q15*/
421 4072668 : s3 += imult1616( 3, step ); /*Q15*/
422 9162954 : WHILE( LT_16( is, sub( n, 1 ) ) )
423 : {
424 5090286 : xup1 = x + add( j, is ); /*Qx*/
425 5090286 : xup3 = xup1 + shl( n4, 1 ); /*Qx*/
426 5090286 : xdn6 = xup3 - sub( shl( j, 1 ), 2 ); /*Qx*/
427 5090286 : xdn8 = xdn6 + shl( n4, 1 ); /*Qx*/
428 :
429 12824622 : FOR( i = is; i < n; i += id )
430 : {
431 7734336 : t1 = L_sub( *xup1, *xdn6 ); /*Qx*/
432 7734336 : *xup1 = L_add( *xup1, *xdn6 ); /*Qx*/
433 7734336 : move32();
434 7734336 : xup1 += n4;
435 7734336 : xdn6 -= n4;
436 :
437 7734336 : t2 = L_sub( *xdn6, *xup1 ); /*Qx*/
438 7734336 : *xdn6 = L_add( *xup1, *xdn6 ); /*Qx*/
439 7734336 : move32();
440 :
441 7734336 : xdn6 += n4;
442 7734336 : t3 = L_add( *xdn8, *xup3 ); /*Qx*/
443 7734336 : *xdn6 = L_sub( *xdn8, *xup3 ); /*Qx*/
444 7734336 : move32();
445 :
446 7734336 : xup3 += n4;
447 7734336 : xdn8 -= n4;
448 :
449 7734336 : t4 = L_add( *xup3, *xdn8 ); /*Qx*/
450 7734336 : *xup1 = L_sub( *xup3, *xdn8 ); /*Qx*/
451 7734336 : move32();
452 :
453 7734336 : t5 = L_sub( t1, t4 ); /*Qx*/
454 7734336 : t1 = L_add( t1, t4 ); /*Qx*/
455 7734336 : t4 = L_sub( t2, t3 ); /*Qx*/
456 7734336 : t2 = L_add( t2, t3 ); /*Qx*/
457 7734336 : *xup3 = L_sub( Mpy_32_16_1( t1, cc3 ), Mpy_32_16_1( t2, ss3 ) ); /*Qx*/
458 7734336 : move32();
459 7734336 : xup3 -= n4;
460 7734336 : *xup3 = L_add( Mpy_32_16_1( t5, cc1 ), Mpy_32_16_1( t4, ss1 ) ); /*Qx*/
461 7734336 : move32();
462 7734336 : *xdn8 = L_sub( Mpy_32_16_1( t5, ss1 ), Mpy_32_16_1( t4, cc1 ) ); /*Qx*/
463 7734336 : move32();
464 :
465 7734336 : xdn8 += n4;
466 7734336 : *xdn8 = L_add( Mpy_32_16_1( t2, cc3 ), Mpy_32_16_1( t1, ss3 ) ); /*Qx*/
467 7734336 : move32();
468 :
469 7734336 : xup1 -= n4;
470 7734336 : xup1 += id;
471 7734336 : xup3 += id;
472 7734336 : xdn6 += id;
473 7734336 : xdn8 += id;
474 : }
475 5090286 : is = sub( shl( id, 1 ), n2 ); /*Q0*/
476 5090286 : id = shl( id, 2 ); /*Q0*/
477 : }
478 : }
479 : }
480 :
481 : /*-----------------------------------------------------------------*
482 : * Length two butterflies
483 : *-----------------------------------------------------------------*/
484 :
485 34067 : is = 1;
486 34067 : move16();
487 34067 : id = 4;
488 34067 : move16();
489 204158 : WHILE( LT_16( is, n ) )
490 : {
491 170091 : xi0 = x + is;
492 170091 : xi1 = xi0 + 1;
493 :
494 5974564 : FOR( i0 = is; i0 <= n; i0 += id )
495 : {
496 5804473 : r1 = *xi0; /*Qx*/
497 5804473 : move32();
498 5804473 : *xi0 = L_add( r1, *xi1 ); /*Qx*/
499 5804473 : move32();
500 5804473 : *xi1 = L_sub( r1, *xi1 ); /*Qx*/
501 5804473 : move32();
502 5804473 : xi0 += id;
503 5804473 : xi1 += id;
504 : }
505 170091 : is = sub( shl( id, 1 ), 1 );
506 170091 : id = shl( id, 2 );
507 : }
508 :
509 : /*-----------------------------------------------------------------*
510 : * Digit reverse counter
511 : *-----------------------------------------------------------------*/
512 :
513 34067 : idx = fft256_read_indexes;
514 34067 : xi0 = &temp[0] - 1;
515 34067 : IF( EQ_16( n, 128 ) )
516 : {
517 0 : FOR( i = 0; i < n; i++ )
518 : {
519 0 : j = *idx++;
520 0 : move16();
521 0 : temp[i] = x[1 + shr( j, 1 )]; /*Qx*/
522 0 : move32();
523 : }
524 : }
525 34067 : ELSE IF( EQ_16( n, 256 ) )
526 : {
527 62708 : FOR( i = 0; i < n; i++ )
528 : {
529 62464 : j = *idx++;
530 62464 : temp[i] = x[1 + j]; /*Qx*/
531 62464 : move32();
532 : }
533 : }
534 33823 : ELSE IF( EQ_16( n, 512 ) )
535 : {
536 8692511 : FOR( i = 0; i < 256; i++ )
537 : {
538 8658688 : j = *idx++;
539 8658688 : temp[i] = x[1 + 2 * j]; /*Qx*/
540 8658688 : move32();
541 8658688 : temp[i + 256] = x[2 + 2 * j]; /*Qx*/
542 8658688 : move32();
543 : }
544 : }
545 : ELSE
546 : {
547 0 : xi0 = x;
548 0 : j = 1;
549 0 : move16();
550 0 : FOR( i = 1; i < n; i++ )
551 : {
552 0 : IF( LT_16( i, j ) )
553 : {
554 0 : xt = x[j]; /*Qx*/
555 0 : x[j] = x[i]; /*Qx*/
556 0 : x[i] = xt; /*Qx*/
557 0 : move32();
558 0 : move32();
559 0 : move32();
560 : }
561 0 : k = shr( n, 1 );
562 0 : WHILE( LT_16( k, j ) )
563 : {
564 0 : j = sub( j, k );
565 0 : k = shr( k, 1 );
566 : }
567 0 : j = add( j, k );
568 : }
569 : }
570 :
571 : /*-----------------------------------------------------------------*
572 : * Normalization
573 : *-----------------------------------------------------------------*/
574 :
575 17413907 : FOR( i = 1; i <= n; i++ )
576 : {
577 17379840 : x[i] = Mpy_32_16_1( xi0[i], n_inv ); /*Qx*/
578 17379840 : move32();
579 : }
580 :
581 34067 : return;
582 : }
|