XenevaOS
Loading...
Searching...
No Matches
assembly.h
Go to the documentation of this file.
1/* ***** BEGIN LICENSE BLOCK *****
2 * Source last modified: $Id: assembly.h,v 1.7 2005/11/10 00:04:40 margotm Exp $
3 *
4 * Portions Copyright (c) 1995-2005 RealNetworks, Inc. All Rights Reserved.
5 *
6 * The contents of this file, and the files included with this file,
7 * are subject to the current version of the RealNetworks Public
8 * Source License (the "RPSL") available at
9 * http://www.helixcommunity.org/content/rpsl unless you have licensed
10 * the file under the current version of the RealNetworks Community
11 * Source License (the "RCSL") available at
12 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
13 * will apply. You may also obtain the license terms directly from
14 * RealNetworks. You may not use this file except in compliance with
15 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
16 * to this file, the RCSL. Please see the applicable RPSL or RCSL for
17 * the rights, obligations and limitations governing use of the
18 * contents of the file.
19 *
20 * This file is part of the Helix DNA Technology. RealNetworks is the
21 * developer of the Original Code and owns the copyrights in the
22 * portions it created.
23 *
24 * This file, and the files included with this file, is distributed
25 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
26 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
27 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
28 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
29 * ENJOYMENT OR NON-INFRINGEMENT.
30 *
31 * Technology Compatibility Kit Test Suite(s) Location:
32 * http://www.helixcommunity.org/content/tck
33 *
34 * Contributor(s):
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/**************************************************************************************
39 * Fixed-point HE-AAC decoder
40 * Jon Recker (jrecker@real.com)
41 * February 2005
42 *
43 * assembly.h - inline assembly language functions and prototypes
44 *
45 * MULSHIFT32(x, y) signed multiply of two 32-bit integers (x and y),
46 * returns top 32-bits of 64-bit result
47 * CLIPTOSHORT(x) convert 32-bit integer to 16-bit short,
48 * clipping to [-32768, 32767]
49 * FASTABS(x) branchless absolute value of signed integer x
50 * CLZ(x) count leading zeros on signed integer x
51 * MADD64(sum64, x, y) 64-bit multiply accumulate: sum64 += (x*y)
52 **************************************************************************************/
53
54#ifndef _ASSEMBLY_H
55#define _ASSEMBLY_H
56
57/* toolchain: MSFT Visual C++
58 * target architecture: x86
59 */
60#if ((defined (_WIN32) && !defined (_WIN32_WCE)) || (defined (__WINS__) && defined (_SYMBIAN)) || (defined (WINCE_EMULATOR)) || (defined (_OPENWAVE_SIMULATOR))) && !defined(__aarch64__)
61
62#pragma warning( disable : 4035 ) /* complains about inline asm not returning a value */
63
64static __inline int MULSHIFT32(int x, int y)
65{
66 __asm {
67 mov eax, x
68 imul y
69 mov eax, edx
70 }
71}
72
73static __inline short CLIPTOSHORT(int x)
74{
75 int sign;
76
77 /* clip to [-32768, 32767] */
78 sign = x >> 31;
79 if (sign != (x >> 15))
80 x = sign ^ ((1 << 15) - 1);
81
82 return (short)x;
83}
84
85static __inline int FASTABS(int x)
86{
87 int sign;
88
89 sign = x >> (sizeof(int) * 8 - 1);
90 x ^= sign;
91 x -= sign;
92
93 return x;
94}
95
96static __inline int CLZ(int x)
97{
98 int numZeros;
99
100 if (!x)
101 return 32;
102
103 /* count leading zeros with binary search */
104 numZeros = 1;
105 if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; }
106 if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; }
107 if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; }
108 if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; }
109
110 numZeros -= ((unsigned int)x >> 31);
111
112 return numZeros;
113}
114
115#ifdef __CW32__
116typedef long long Word64;
117#else
118typedef __int64 Word64;
119#endif
120
121typedef union _U64 {
122 Word64 w64;
123 struct {
124 /* x86 = little endian */
125 unsigned int lo32;
126 signed int hi32;
127 } r;
128} U64;
129
130/* returns 64-bit value in [edx:eax] */
131static __inline Word64 MADD64(Word64 sum64, int x, int y)
132{
133#if (defined (_SYMBIAN_61_) || defined (_SYMBIAN_70_)) && defined (__WINS__) && !defined (__CW32__)
134/* Workaround for the Symbian emulator because of non existing longlong.lib and
135 * hence __allmul not defined. */
136 __asm {
137 mov eax, x
138 imul y
139 add dword ptr sum64, eax
140 adc dword ptr sum64 + 4, edx
141 }
142#else
143 sum64 += (Word64)x * (Word64)y;
144#endif
145
146 return sum64;
147}
148
149/* toolchain: MSFT Embedded Visual C++
150 * target architecture: ARM v.4 and above (require 'M' type processor for 32x32->64 multiplier)
151 */
152#elif defined (_WIN32) && defined (_WIN32_WCE) && defined (ARM)
153
154static __inline short CLIPTOSHORT(int x)
155{
156 int sign;
157
158 /* clip to [-32768, 32767] */
159 sign = x >> 31;
160 if (sign != (x >> 15))
161 x = sign ^ ((1 << 15) - 1);
162
163 return (short)x;
164}
165
166static __inline int FASTABS(int x)
167{
168 int sign;
169
170 sign = x >> (sizeof(int) * 8 - 1);
171 x ^= sign;
172 x -= sign;
173
174 return x;
175}
176
177static __inline int CLZ(int x)
178{
179 int numZeros;
180
181 if (!x)
182 return 32;
183
184 /* count leading zeros with binary search (function should be 17 ARM instructions total) */
185 numZeros = 1;
186 if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; }
187 if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; }
188 if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; }
189 if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; }
190
191 numZeros -= ((unsigned int)x >> 31);
192
193 return numZeros;
194}
195
196/* implemented in asmfunc.s */
197#ifdef __cplusplus
198extern "C" {
199#endif
200
201typedef __int64 Word64;
202
203typedef union _U64 {
204 Word64 w64;
205 struct {
206 /* ARM WinCE = little endian */
207 unsigned int lo32;
208 signed int hi32;
209 } r;
210} U64;
211
212/* manual name mangling for just this platform (must match labels in .s file) */
213#define MULSHIFT32 raac_MULSHIFT32
214#define MADD64 raac_MADD64
215
216int MULSHIFT32(int x, int y);
217Word64 MADD64(Word64 sum64, int x, int y);
218
219#ifdef __cplusplus
220}
221#endif
222
223/* toolchain: ARM ADS or RealView
224 * target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier)
225 */
226#elif defined (XXX__arm) && defined (__ARMCC_VERSION)
227
228static __inline int MULSHIFT32(int x, int y)
229{
230 /* rules for smull RdLo, RdHi, Rm, Rs:
231 * RdHi != Rm
232 * RdLo != Rm
233 * RdHi != RdLo
234 */
235 int zlow;
236 __asm {
237 smull zlow,y,x,y
238 }
239
240 return y;
241}
242
243static __inline short CLIPTOSHORT(int x)
244{
245 int sign;
246
247 /* clip to [-32768, 32767] */
248 sign = x >> 31;
249 if (sign != (x >> 15))
250 x = sign ^ ((1 << 15) - 1);
251
252 return (short)x;
253}
254
255static __inline int FASTABS(int x)
256{
257 int sign;
258
259 sign = x >> (sizeof(int) * 8 - 1);
260 x ^= sign;
261 x -= sign;
262
263 return x;
264}
265
266static __inline int CLZ(int x)
267{
268 int numZeros;
269
270 if (!x)
271 return 32;
272
273 /* count leading zeros with binary search (function should be 17 ARM instructions total) */
274 numZeros = 1;
275 if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; }
276 if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; }
277 if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; }
278 if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; }
279
280 numZeros -= ((unsigned int)x >> 31);
281
282 return numZeros;
283
284/* ARM code would look like this, but do NOT use inline asm in ADS for this,
285 because you can't safely use the status register flags intermixed with C code
286
287 __asm {
288 mov numZeros, #1
289 tst x, 0xffff0000
290 addeq numZeros, numZeros, #16
291 moveq x, x, lsl #16
292 tst x, 0xff000000
293 addeq numZeros, numZeros, #8
294 moveq x, x, lsl #8
295 tst x, 0xf0000000
296 addeq numZeros, numZeros, #4
297 moveq x, x, lsl #4
298 tst x, 0xc0000000
299 addeq numZeros, numZeros, #2
300 moveq x, x, lsl #2
301 sub numZeros, numZeros, x, lsr #31
302 }
303*/
304/* reference:
305 numZeros = 0;
306 while (!(x & 0x80000000)) {
307 numZeros++;
308 x <<= 1;
309 }
310*/
311}
312
313typedef __int64 Word64;
314
315typedef union _U64 {
316 Word64 w64;
317 struct {
318 /* ARM ADS = little endian */
319 unsigned int lo32;
320 signed int hi32;
321 } r;
322} U64;
323
324static __inline Word64 MADD64(Word64 sum64, int x, int y)
325{
326 U64 u;
327 u.w64 = sum64;
328
329 __asm {
330 smlal u.r.lo32, u.r.hi32, x, y
331 }
332
333 return u.w64;
334}
335
336/* toolchain: ARM gcc
337 * target architecture: ARM v.4 and above (requires 'M' type processor for 32x32->64 multiplier)
338 */
339#elif defined(__GNUC__) && defined(XXXX__arm__)
340
341static inline int MULSHIFT32(int x, int y)
342{
343 int zlow;
344 asm ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (y) : "r" (x), "1" (y) : "cc");
345 return y;
346}
347/*
348static inline short CLIPTOSHORT(int x)
349{
350 int sign;
351
352 // clip to [-32768, 32767] //
353 sign = x >> 31;
354 if (sign != (x >> 15))
355 x = sign ^ ((1 << 15) - 1);
356
357 return (short)x;
358}
359*/
360static inline short CLIPTOSHORT(int x)
361{
362 asm ("ssat %0, #16, %1" : "=r" (x) : "r" (x));
363 return x;
364}
365
366/* From coder.h, ORIGINAL:
367clip to [-2^n, 2^n-1], valid range of n = [1, 30]
368//TODO (FB) Is there a better way ?
369*/
370#define CLIP_2N(y, n) { \
371 int sign = (y) >> 31; \
372 if (sign != (y) >> (n)) { \
373 (y) = sign ^ ((1 << (n)) - 1); \
374 } \
375}
376
377/* From coder.h, ORIGINAL:
378 do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit)
379*/
380//TODO (FB) Is there a better way ?
381#define CLIP_2N_SHIFT(y, n) { \
382 int sign = (y) >> 31; \
383 if (sign != (y) >> (30 - (n))) { \
384 (y) = sign ^ (0x3fffffff); \
385 } else { \
386 (y) = (y) << (n); \
387 } \
388 }
389
390
391
392#define FASTABS(x) abs(x) //FB
393#define CLZ(x) __builtin_clz(x) //FB
394
395//Reverse byte order (16 bit) //FB
396static inline unsigned int REV16( unsigned int value)
397{
398 asm ("rev16 %0, %1" : "=r" (value) : "r" (value) );
399 return(value);
400}
401
402//Reverse byte order (32 bit) //FB
403static inline unsigned int REV32( unsigned int value)
404{
405 asm ("rev %0, %1" : "=r" (value) : "r" (value) );
406 return(value);
407}
408
409
410typedef long long Word64;
411
412typedef union _U64 {
413 Word64 w64;
414 struct {
415 /* little endian */
416 unsigned int lo32;
417 signed int hi32;
418 } r;
419} U64;
420
421static inline Word64 MADD64(Word64 sum64, int x, int y)
422{
423 U64 u;
424 u.w64 = sum64;
425 asm ("smlal %0,%1,%2,%3" : "+&r" (u.r.lo32), "+&r" (u.r.hi32) : "r" (x), "r" (y) : "cc");
426 return u.w64;
427}
428
429/* toolchain: x86 gcc
430 * target architecture: x86
431 */
432#elif defined(__GNUC__) && (defined(__i386__) || defined(__amd64__) || defined(__APPLE__)) || (defined (_SOLARIS) && !defined (__GNUC__) && defined(_SOLARISX86))
433
434typedef long long Word64;
435
436static __inline__ int MULSHIFT32(int x, int y)
437{
438 int z;
439
440 z = (Word64)x * (Word64)y >> 32;
441
442 return z;
443}
444
445static __inline short CLIPTOSHORT(int x)
446{
447 int sign;
448
449 /* clip to [-32768, 32767] */
450 sign = x >> 31;
451 if (sign != (x >> 15))
452 x = sign ^ ((1 << 15) - 1);
453
454 return (short)x;
455}
456
457static __inline int FASTABS(int x)
458{
459 int sign;
460
461 sign = x >> (sizeof(int) * 8 - 1);
462 x ^= sign;
463 x -= sign;
464
465 return x;
466}
467
468static __inline int CLZ(int x)
469{
470 int numZeros;
471
472 if (!x)
473 return 32;
474
475 /* count leading zeros with binary search (function should be 17 ARM instructions total) */
476 numZeros = 1;
477 if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; }
478 if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; }
479 if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; }
480 if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; }
481
482 numZeros -= ((unsigned int)x >> 31);
483
484 return numZeros;
485}
486
487typedef union _U64 {
488 Word64 w64;
489 struct {
490 /* x86 = little endian */
491 unsigned int lo32;
492 signed int hi32;
493 } r;
494} U64;
495
496static __inline Word64 MADD64(Word64 sum64, int x, int y)
497{
498 sum64 += (Word64)x * (Word64)y;
499
500 return sum64;
501}
502
503#elif defined(ARDUINO) || defined(ESP32) || defined(ESP_PLATFORM) || defined(__aarch64__) || defined(__GNUC__) && (defined(__powerpc__) || defined(__POWERPC__)) || (defined (_SOLARIS) && !defined (__GNUC__) && !defined (_SOLARISX86))
504
505typedef long long Word64;
506
507static __inline__ int MULSHIFT32(int x, int y)
508{
509 int z;
510
511 z = (Word64)x * (Word64)y >> 32;
512
513 return z;
514}
515
516static __inline short CLIPTOSHORT(int x)
517{
518 int sign;
519
520 /* clip to [-32768, 32767] */
521 sign = x >> 31;
522 if (sign != (x >> 15))
523 x = sign ^ ((1 << 15) - 1);
524
525 return (short)x;
526}
527
528static __inline int FASTABS(int x)
529{
530 int sign;
531
532 sign = x >> (sizeof(int) * 8 - 1);
533 x ^= sign;
534 x -= sign;
535
536 return x;
537}
538
539static __inline int CLZ(int x)
540{
541 int numZeros;
542
543 if (!x)
544 return 32;
545
546 /* count leading zeros with binary search (function should be 17 ARM instructions total) */
547 numZeros = 1;
548 if (!((unsigned int)x >> 16)) { numZeros += 16; x <<= 16; }
549 if (!((unsigned int)x >> 24)) { numZeros += 8; x <<= 8; }
550 if (!((unsigned int)x >> 28)) { numZeros += 4; x <<= 4; }
551 if (!((unsigned int)x >> 30)) { numZeros += 2; x <<= 2; }
552
553 numZeros -= ((unsigned int)x >> 31);
554
555 return numZeros;
556}
557
558typedef union _U64 {
559 Word64 w64;
560 struct {
561#if defined(__POWERPC__) || defined(__powerpc__)
562 /* PowerPC = big endian */
563 signed int hi32;
564 unsigned int lo32;
565#else
566 unsigned int lo32;
567 signed int hi32;
568#endif
569 } r;
570} U64;
571
572static __inline Word64 MADD64(Word64 sum64, int x, int y)
573{
574 sum64 += (Word64)x * (Word64)y;
575
576 return sum64;
577}
578
579/* From coder.h, ORIGINAL:
580clip to [-2^n, 2^n-1], valid range of n = [1, 30]
581//TODO (FB) Is there a better way ?
582*/
583#define CLIP_2N(y, n) { \
584 int sign = (y) >> 31; \
585 if (sign != (y) >> (n)) { \
586 (y) = sign ^ ((1 << (n)) - 1); \
587 } \
588}
589
590/* From coder.h, ORIGINAL:
591 do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit)
592*/
593//TODO (FB) Is there a better way ?
594#define CLIP_2N_SHIFT(y, n) { \
595 int sign = (y) >> 31; \
596 if (sign != (y) >> (30 - (n))) { \
597 (y) = sign ^ (0x3fffffff); \
598 } else { \
599 (y) = (y) << (n); \
600 } \
601 }
602
603
604
605//#define FASTABS(x) abs(x) //FB
606//#define CLZ(x) __builtin_clz(x) //FB
607
608#else
609
610#error Unsupported platform in assembly.h
611
612#endif /* platforms */
613
614#ifndef CLIP_2N
615#define CLIP_2N(y, n) { \
616 int sign = (y) >> 31; \
617 if (sign != (y) >> (n)) { \
618 (y) = sign ^ ((1 << (n)) - 1); \
619 } \
620}
621#endif
622
623#ifndef CLIP_2N_SHIFT
624/* From coder.h, ORIGINAL:
625 do y <<= n, clipping to range [-2^30, 2^30 - 1] (i.e. output has one guard bit)
626*/
627//TODO (FB) Is there a better way ?
628#define CLIP_2N_SHIFT(y, n) { \
629 int sign = (y) >> 31; \
630 if (sign != (y) >> (30 - (n))) { \
631 (y) = sign ^ (0x3fffffff); \
632 } else { \
633 (y) = (y) << (n); \
634 } \
635 }
636#endif
637
638#endif /* _ASSEMBLY_H */
#define sign(x)
Definition draw.cpp:36
int y
Definition layout.c:118
int x
Definition layout.c:118